/// <summary> /// Initializes an InterWavePixelMap with color image #bm#. This constructor /// performs the wavelet decomposition of image #bm# and records the /// corresponding wavelet coefficients. Argument #mask# is an optional /// bilevel image specifying the masked pixels(see \Ref{ IW44Image.h}). /// Argument #crcbmode# specifies how the chrominance information should be /// encoded(see \Ref{ CRCBMode}). /// </summary> /// <param name="bm"></param> /// <param name="mask"></param> /// <param name="mode"></param> public unsafe void InitializeEncoder(IPixelMap pm, Bitmap gmask = null, YCrCbMode crcbmode = YCrCbMode.Normal) { /* Free */ CloseEncoder(); // Handle CRCB mode switch (crcbmode) { case YCrCbMode.None: _CrCbHalf = true; _CrCbDelay = -1; break; case YCrCbMode.Half: _CrCbHalf = true; _CrCbDelay = 10; break; case YCrCbMode.Normal: _CrCbHalf = false; _CrCbDelay = 10; break; case YCrCbMode.Full: _CrCbHalf = false; _CrCbDelay = 0; break; } // Prepare mask information sbyte *msk8 = (sbyte *)IntPtr.Zero; int mskrowsize = 0; Bitmap mask = gmask; GCHandle hMask = default(GCHandle); if (mask != null) { hMask = GCHandle.Alloc(mask.Data, GCHandleType.Pinned); msk8 = (sbyte *)hMask.AddrOfPinnedObject(); mskrowsize = mask.GetRowSize(); } /* Create */ int width = pm.Width; int height = pm.Height; sbyte[] sYBuffer = new sbyte[width * height]; GCHandle hYBuffer = GCHandle.Alloc(sYBuffer, GCHandleType.Pinned); sbyte * yBuffer = (sbyte *)hYBuffer.AddrOfPinnedObject(); // Create maps InterWaveMapEncoder eymap = new InterWaveMapEncoder(width, height); _YMap = eymap; GCHandle hData = GCHandle.Alloc(pm.Data, GCHandleType.Pinned); Pixel * pData = (Pixel *)hData.AddrOfPinnedObject(); // Create chrominance maps if (_CrCbDelay >= 0) { sbyte[] sCbBuffer = new sbyte[width * height]; GCHandle hCbBuffer = GCHandle.Alloc(sCbBuffer, GCHandleType.Pinned); sbyte * cbBuffer = (sbyte *)hCbBuffer.AddrOfPinnedObject(); sbyte[] sCrBuffer = new sbyte[width * height]; GCHandle hCrBuffer = GCHandle.Alloc(sCrBuffer, GCHandleType.Pinned); sbyte * crBuffer = (sbyte *)hCrBuffer.AddrOfPinnedObject(); InterWaveMapEncoder ecbmap = new InterWaveMapEncoder(width, height); _CbMap = ecbmap; InterWaveMapEncoder ecrmap = new InterWaveMapEncoder(width, height); _CrMap = ecrmap; // Color space conversion from RGB to YCbCr and channel separation InterWaveTransform.Rgb2YCbCr(pData, width, height, width * 3, yBuffer, cbBuffer, crBuffer, width); // Create YMap eymap.Create(yBuffer, width, msk8, mskrowsize); // Create CbMap ecbmap.Create(cbBuffer, width, msk8, mskrowsize); // Create CrMap ecrmap.Create(crBuffer, width, msk8, mskrowsize); // Perform chrominance reduction (CrCbHalf) if (_CrCbHalf) { ecbmap.Slashres(2); ecrmap.Slashres(2); } if (hCbBuffer.IsAllocated) { hCbBuffer.Free(); } if (hCrBuffer.IsAllocated) { hCrBuffer.Free(); } } else { // Fill buffer with luminance information InterWaveTransform.Rgb2Y(pData, width, height, pm.GetRowSize(), yBuffer, width); // Create YMAP eymap.Create(yBuffer, width, msk8, mskrowsize); // Inversion for gray images sbyte *e = yBuffer + width * height; for (sbyte *b = yBuffer; b < e; b++) { *b = (sbyte)(255 - *b); } } if (hMask.IsAllocated) { hMask.Free(); } hData.Free(); hYBuffer.Free(); }
public static InterWaveImage CreateEncoder(IPixelMap map, IBitmap mask = null, YCrCbMode mode = YCrCbMode.Normal) { throw new NotImplementedException(); }