/// <summary> 建立使用指定像素格式的<see cref="WzCanvas"/>實體 </summary> /// <param name="name"> <see cref="WzCanvas"/>的名稱 </param> /// <param name="format"> <see cref="WzCanvas"/>的像素格式 </param> public WzCanvas(string name, WzCanvasFormat format = WzCanvasFormat.B8G8R8A8) : base(name) { this.CanvasProperty = new WzProperty(null); this.Unknow1_Byte = 0; this.Width = 0; this.Height = 0; this.Format = format; this.Scale = 0; this.Unknow2_Int = 0; this.DataSize = 0; this.mCanvasOffset = 0; this.mCanvasData = null; this.mStream = null; }
/// <summary> </summary> public static unsafe byte[] Compress(WzCanvasFormat format, byte scale, int width, int height, Bitmap src) { PixelFormat pxFormat = (format == WzCanvasFormat.B5G6R5) ? PixelFormat.Format16bppRgb565 : PixelFormat.Format32bppArgb; int cw = width >> scale, ch = height >> scale; int cbSize = (format == WzCanvasFormat.B5G6R5 || format == WzCanvasFormat.B4G4R4A4) ? 2 : (format == WzCanvasFormat.B8G8R8A8) ? 4 : 1; Rectangle rect = new Rectangle(0, 0, cw, ch); Bitmap bmp = new Bitmap(src, cw, ch).Clone(rect, pxFormat); BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.WriteOnly, pxFormat); byte[] compress = null; switch (format) { case WzCanvasFormat.B4G4R4A4: compress = new byte[cw * ch * cbSize]; fixed(byte *pDest = compress) { Pack4444(pDest, (byte *)bmpData.Scan0, cw, ch); } break; case WzCanvasFormat.B5G6R5: case WzCanvasFormat.B8G8R8A8: compress = new byte[bmpData.Stride * bmpData.Height]; Marshal.Copy(bmpData.Scan0, compress, 0, compress.Length); break; case WzCanvasFormat.DDS_DXT3: { byte[] buffer = new byte[bmpData.Stride * bmpData.Height]; Marshal.Copy(bmpData.Scan0, buffer, 0, buffer.Length); compress = dxt.compressImage(buffer, cw, ch, dxt.kDxt3); } break; case WzCanvasFormat.DDS_DXT5: { byte[] buffer = new byte[bmpData.Stride * bmpData.Height]; Marshal.Copy(bmpData.Scan0, buffer, 0, buffer.Length); compress = dxt.compressImage(buffer, cw, ch, dxt.kDxt5); } break; } bmp.UnlockBits(bmpData); return(CanvasZlibTool.Compress(compress, compress.Length)); }
/// <summary> </summary> public static unsafe Bitmap Decompress(WzCanvasFormat format, byte scale, int width, int height, byte[] datas) { int cbPixel = width * height; PixelFormat pxFormat = (format == WzCanvasFormat.B5G6R5) ? PixelFormat.Format16bppRgb565 : PixelFormat.Format32bppArgb; Bitmap bmp = new Bitmap(width, height, pxFormat); BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, pxFormat); int decw = width >> scale, dech = height >> scale; int cbSize = (format == WzCanvasFormat.B5G6R5 || format == WzCanvasFormat.B4G4R4A4) ? 2 : (format == WzCanvasFormat.B8G8R8A8) ? 4 : 1; byte[] buffer = new byte[cbPixel * cbSize]; ZoomInPixels(buffer, CanvasZlibTool.Decompress(datas, decw * dech * cbSize), decw, dech, 1 << scale, cbSize); switch (format) { case WzCanvasFormat.B4G4R4A4: fixed(byte *pSrc = buffer) { Unpack4444((int *)bmpData.Scan0, (short *)pSrc, width, height); } break; case WzCanvasFormat.B5G6R5: case WzCanvasFormat.B8G8R8A8: Marshal.Copy(buffer, 0, bmpData.Scan0, buffer.Length); break; case WzCanvasFormat.DDS_DXT3: { byte[] imagedata = dxt.decompressImage(buffer, width, height, dxt.kDxt3); Marshal.Copy(imagedata, 0, bmpData.Scan0, imagedata.Length); } break; case WzCanvasFormat.DDS_DXT5: { byte[] imagedata = dxt.decompressImage(buffer, width, height, dxt.kDxt5); Marshal.Copy(imagedata, 0, bmpData.Scan0, imagedata.Length); } break; } bmp.UnlockBits(bmpData); return(bmp); }