public static unsafe Bitmap GenerateMip(this Bitmap bmp, int level) { if (level <= 1) { return((Bitmap)bmp.Clone()); } int scale = 1 << (level - 1); int w = bmp.Width / scale, h = bmp.Height / scale; Bitmap dst = new Bitmap(w, h, bmp.PixelFormat); //Step-scale indexed elements if (bmp.IsIndexed()) { BitmapData srcData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat); BitmapData dstData = dst.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, bmp.PixelFormat); float xStep = (float)bmp.Width / w; float yStep = (float)bmp.Height / h; int x, y; float fx, fy; byte *sPtr, dPtr = (byte *)dstData.Scan0; if (bmp.PixelFormat == PixelFormat.Format8bppIndexed) { for (y = 0, fy = 0.5f; y < h; y++, fy += yStep, dPtr += dstData.Stride) { sPtr = (byte *)srcData.Scan0 + ((int)fy * srcData.Stride); for (x = 0, fx = 0.5f; x < w; x++, fx += xStep) { dPtr[x] = sPtr[(int)fx]; } } } else { for (y = 0, fy = 0.5f; y < h; y++, fy += yStep, dPtr += dstData.Stride) { sPtr = (byte *)srcData.Scan0 + ((int)fy * srcData.Stride); int b = 0, ind; for (x = 0, fx = 0.5f; x < w; x++, fx += xStep) { ind = (int)fx; if ((x & 1) == 0) { if ((ind & 1) == 0) { b = sPtr[ind >> 1] & 0xF0; } else { b = sPtr[ind >> 1] << 4; } } else { if ((ind & 1) == 0) { b |= sPtr[ind >> 1] >> 4; } else { b |= sPtr[ind >> 1] & 0xF; } dPtr[x >> 1] = (byte)b; } } if ((x & 1) != 0) { dPtr[x >> 1] = (byte)b; } } } bmp.UnlockBits(srcData); dst.UnlockBits(dstData); } else { using (Graphics g = Graphics.FromImage(dst)) { g.CompositingMode = CompositingMode.SourceCopy; g.CompositingQuality = CompositingQuality.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.PixelOffsetMode = PixelOffsetMode.HighQuality; g.SmoothingMode = SmoothingMode.AntiAlias; g.DrawImage(bmp, new Rectangle(0, 0, w, h)); } } return(dst); }
public virtual FileMap EncodeTPLTextureIndexed(Bitmap src, int mipLevels, WiiPaletteFormat format, out FileMap paletteFile) { if (!src.IsIndexed()) throw new ArgumentException("Source image must be indexed."); FileMap texMap = EncodeTPLTexture(src, mipLevels); paletteFile = EncodeTPLPalette(src.Palette, format); return texMap; }
public virtual FileMap EncodeTPLTexture(Bitmap src, int mipLevels) { int w = src.Width, h = src.Height; int bw = BlockWidth, bh = BlockHeight; PixelFormat fmt = src.IsIndexed() ? src.PixelFormat : PixelFormat.Format32bppArgb; FileMap fileView = FileMap.FromTempFile(GetFileSize(w, h, mipLevels) + TPLTextureHeader.Size); try { //Build TPL header TPLTextureHeader* tex = (TPLTextureHeader*)fileView.Address; tex->_wrapS = 0; tex->_wrapT = 0; tex->_minFilter = 1; tex->_magFilter = 1; tex->_minLOD = 0; tex->_maxLOD = (short)(mipLevels - 1); tex->PixelFormat = RawFormat; tex->_width = (ushort)w; tex->_height = (ushort)h; tex->_data = TPLTextureHeader.Size; int sStep = bw * Image.GetPixelFormatSize(fmt) / 8; int dStep = bw * bh * BitsPerPixel / 8; VoidPtr baseAddr = fileView.Address; using (DIB dib = DIB.FromBitmap(src, bw, bh, fmt)) for (int i = 1; i <= mipLevels; i++) EncodeLevel(baseAddr + tex->_data, dib, src, dStep, sStep, i); return fileView; } catch (Exception x) { MessageBox.Show(x.ToString()); fileView.Dispose(); return null; } }
public virtual FileMap EncodeTEX0Texture(Bitmap src, int mipLevels) { int w = src.Width, h = src.Height; int bw = BlockWidth, bh = BlockHeight; PixelFormat fmt = src.IsIndexed() ? src.PixelFormat : PixelFormat.Format32bppArgb; FileMap fileView = FileMap.FromTempFile(GetFileSize(w, h, mipLevels) + 0x40); try { //Build TEX header TEX0v1* header = (TEX0v1*)fileView.Address; *header = new TEX0v1(w, h, RawFormat, mipLevels); int sStep = bw * Image.GetPixelFormatSize(fmt) / 8; int dStep = bw * bh * BitsPerPixel / 8; using (DIB dib = DIB.FromBitmap(src, bw, bh, fmt)) for (int i = 1; i <= mipLevels; i++) EncodeLevel(header->PixelData, dib, src, dStep, sStep, i); return fileView; } catch (Exception x) { MessageBox.Show(x.ToString()); fileView.Dispose(); return null; } }
public virtual FileMap EncodeREFTTextureIndexed(Bitmap src, int mipLevels, WiiPaletteFormat format) { if (!src.IsIndexed()) throw new ArgumentException("Source image must be indexed."); return EncodeREFTTexture(src, mipLevels, format); }
public virtual FileMap EncodeREFTTexture(Bitmap src, int mipLevels, WiiPaletteFormat format) { int w = src.Width, h = src.Height; int bw = BlockWidth, bh = BlockHeight; ColorPalette pal = src.Palette; PixelFormat fmt = src.IsIndexed() ? src.PixelFormat : PixelFormat.Format32bppArgb; FileMap fileView = FileMap.FromTempFile(GetFileSize(w, h, mipLevels) + 0x20 + (pal != null ? (pal.Entries.Length * 2) : 0)); try { //Build REFT image header REFTImageHeader* header = (REFTImageHeader*)fileView.Address; *header = new REFTImageHeader((ushort)w, (ushort)h, (byte)RawFormat, (byte)format, (ushort)(pal != null ? pal.Entries.Length : 0), (uint)fileView.Length - 0x20 - (uint)(pal != null ? (pal.Entries.Length * 2) : 0), (byte)(mipLevels - 1)); int sStep = bw * Image.GetPixelFormatSize(fmt) / 8; int dStep = bw * bh * BitsPerPixel / 8; using (DIB dib = DIB.FromBitmap(src, bw, bh, fmt)) for (int i = 1; i <= mipLevels; i++) EncodeLevel((VoidPtr)header + 0x20, dib, src, dStep, sStep, i); if (pal != null) { int count = pal.Entries.Length; switch (format) { case WiiPaletteFormat.IA8: { IA8Pixel* dPtr = (IA8Pixel*)header->PaletteData; for (int i = 0; i < count; i++) dPtr[i] = (IA8Pixel)pal.Entries[i]; break; } case WiiPaletteFormat.RGB565: { wRGB565Pixel* dPtr = (wRGB565Pixel*)header->PaletteData; for (int i = 0; i < count; i++) dPtr[i] = (wRGB565Pixel)pal.Entries[i]; break; } case WiiPaletteFormat.RGB5A3: { wRGB5A3Pixel* dPtr = (wRGB5A3Pixel*)header->PaletteData; for (int i = 0; i < count; i++) dPtr[i] = (wRGB5A3Pixel)pal.Entries[i]; break; } } } return fileView; } catch (Exception x) { MessageBox.Show(x.ToString()); fileView.Dispose(); return null; } }