/// <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();
        }
Esempio n. 2
0
 public static InterWaveImage CreateEncoder(IPixelMap map, IBitmap mask = null, YCrCbMode mode = YCrCbMode.Normal)
 {
     throw new NotImplementedException();
 }