Пример #1
0
        /// <summary>
        /// Encodes the input image (raw data) to WSQ.
        /// </summary>
        /// <param name="image">The input image.</param>
        /// <param name="bitrate">The bit rate (in bits per pixels).</param>
        /// <param name="comment">An optional comment that is added to the WSQ image.</param>
        /// <returns>WSQ Encoded image.</returns>
        public static byte[] Encode(RawImageData image, float bitrate, string comment)
        {
            if (image == null || image.IsEmpty)
                return new byte[0];

            var inputData = image.Data;
            var inputDataPtr = Marshal.AllocHGlobal(inputData.Length);
            var outputDataPtr = IntPtr.Zero;
            try
            {
                Marshal.Copy(inputData, 0, inputDataPtr, inputData.Length);

                var outputLength = 0;
                var result = NativeMethods.wsq_encode(
                    out outputDataPtr, out outputLength, bitrate, inputDataPtr, image.Width, image.Height,
                    image.PixelDepth, image.Resolution, comment ?? string.Empty);

                if (result == 0) // ok
                {
                    var outputData = new byte[outputLength];
                    Marshal.Copy(outputDataPtr, outputData, 0, outputLength);
                    return outputData;
                }
            }
            finally
            {
                if (inputDataPtr != IntPtr.Zero)
                    Marshal.FreeHGlobal(inputDataPtr);
                if (outputDataPtr != IntPtr.Zero)
                    NativeMethods.free_mem(outputDataPtr);
            }

            return null;
        }
Пример #2
0
        //public static unsafe RawImageData WpfImageToImageInfo(BitmapImage image)
        //{
        //    if (image == null) throw new ArgumentException("image");

        //    // 16bpp grayscale is not really supported by the underlying codec.
        //    if (/* image.Format != PixelFormats.Gray16 && */ image.Format != PixelFormats.Gray8)
        //        throw new ArgumentException("Unsupported image format.");

        //    return null;
        //    //if (image.PixelFormat != PixelFormat.Format16bppGrayScale && image.PixelFormat != PixelFormat.Format8bppIndexed)
        //    //    throw new ArgumentException("Unsupported image format.");

        //    //var info = new WsqImageInfo()
        //    //{
        //    //    Resolution = (int)image.HorizontalResolution,
        //    //    Width = image.Width,
        //    //    Height = image.Height,
        //    //    Lossy = true,
        //    //    PixelDepth = image.PixelFormat == PixelFormat.Format8bppIndexed ? 8 : 16
        //    //};

        //    //var mul = info.PixelDepth == 8 ? 1 : 2;
        //    //var w = info.Width;
        //    //var h = info.Height;

        //    //info.Data = new byte[w * h * mul];
        //    //var bmpData = image.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, image.PixelFormat);
        //    //try
        //    //{
        //    //    fixed (byte* infoData = info.Data)
        //    //    {
        //    //        var dest = infoData;
        //    //        var source = (byte*)bmpData.Scan0;
        //    //        for (int i = 0; i < h; i++)
        //    //        {
        //    //            NativeMethods.CopyMemory(dest, source, w * mul);
        //    //            dest += w * mul;
        //    //            source += bmpData.Stride;
        //    //        }
        //    //    }
        //    //}
        //    //finally
        //    //{
        //    //    image.UnlockBits(bmpData);
        //    //}

        //    //return info;
        //}

        public static BitmapSource ImageInfoToWpfImage(RawImageData info)
        {
            const int defaultDpi = 96; // Use this one if resolution not set in the wsq file.

            if (info == null || info.IsEmpty) throw new ArgumentException("info");

            // 16bpp grayscale is not really supported by the underlying codec.
            if (info.PixelDepth != 8) throw new NotSupportedException(
                "Source image must have a pixel depth of exactly 8 bpp.");

            var pformat = PixelFormats.Gray8; // The output pixel format
            var bytesPerPixel = pformat.BitsPerPixel / 8;
            var data = info.Data;
            var w = info.Width;
            var h = info.Height;
            var dpi = info.Resolution > 0 ? info.Resolution : defaultDpi;
            // Compute the stride
            var stride = w * bytesPerPixel;
            var modulo = stride % 4;
            if (modulo != 0) stride += 4 - modulo;

            var pixels = new byte[stride * h * bytesPerPixel]; // The output image data
            // Fill it
            var garbage = stride - w * bytesPerPixel;
            for (var i = 0; i < w * h; i++)
            {
                var y = stride > 0 ? i / w : h - i / w;
                var j = i * bytesPerPixel + y * garbage;
                pixels[j] = data[i];
            }

            return BitmapSource.Create(w, h, (double)dpi, (double)dpi, pformat, null, pixels, stride);
        }
Пример #3
0
        public static unsafe Bitmap ImageInfoToGdiImage(RawImageData info)
        {
            if (info == null || info.IsEmpty)
            {
                throw new ArgumentException("info");
            }

            // 16bpp grayscale is not really supported by the underlying codec.
            if (info.PixelDepth != 8)
            {
                throw new NotSupportedException(
                          "Source image must have a pixel depth of exactly 8 bpp.");
            }

            var pformat = info.PixelDepth == 8 ?
                          PixelFormat.Format8bppIndexed : PixelFormat.Format16bppGrayScale;

            var mul = info.PixelDepth == 8 ? 1 : 2;
            var w   = info.Width;
            var h   = info.Height;

            var image = new Bitmap(w, h, pformat);

            var bmpData = image.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly, pformat);

            try
            {
                fixed(byte *infoData = info.Data)
                {
                    var source = infoData;
                    var dest   = (byte *)bmpData.Scan0;

                    for (int i = 0; i < h; i++)
                    {
                        NativeMethods.CopyMemory(dest, source, w * mul);
                        dest   += bmpData.Stride;
                        source += w * mul;
                    }
                }
            }
            finally
            {
                image.UnlockBits(bmpData);
            }

            if (info.PixelDepth == 8)
            {
                // For some crazy reason, we have to write the palette in this roundabout fashion.
                var palette = image.Palette;
                for (int i = 0; i < 256; i++)
                {
                    palette.Entries[i] = Color.FromArgb(i, i, i);
                }
                image.Palette = palette;
            }

            SafeSetResolution(image, info.Resolution);
            return(image);
        }
Пример #4
0
        public static unsafe Bitmap ImageInfoToGdiImage(RawImageData info)
        {
            if (info == null || info.IsEmpty) throw new ArgumentException("info");

            // 16bpp grayscale is not really supported by the underlying codec.
            if (info.PixelDepth != 8) throw new NotSupportedException(
                "Source image must have a pixel depth of exactly 8 bpp.");

            var pformat = info.PixelDepth == 8 ?
                PixelFormat.Format8bppIndexed : PixelFormat.Format16bppGrayScale;

            var mul = info.PixelDepth == 8 ? 1 : 2;
            var w = info.Width;
            var h = info.Height;

            var image = new Bitmap(w, h, pformat);

            var bmpData = image.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly, pformat);
            try
            {
                fixed (byte* infoData = info.Data)
                {
                    var source = infoData;
                    var dest = (byte*)bmpData.Scan0;
                    for (int i = 0; i < h; i++)
                    {
                        NativeMethods.CopyMemory(dest, source, w * mul);
                        dest += bmpData.Stride;
                        source += w * mul;
                    }
                }

            }
            finally
            {
                image.UnlockBits(bmpData);
            }

            if (info.PixelDepth == 8)
            {
                // For some crazy reason, we have to write the palette in this roundabout fashion.
                var palette = image.Palette;
                for (int i = 0; i < 256; i++)
                    palette.Entries[i] = Color.FromArgb(i, i, i);
                image.Palette = palette;
            }

            SafeSetResolution(image, info.Resolution);
            return image;
        }
Пример #5
0
        public static unsafe RawImageData GdiImageToImageInfo(Bitmap image)
        {
            if (image == null)
            {
                throw new ArgumentException("image");
            }

            // 16bpp grayscale is not really supported by the underlying codec.
            if (/* image.PixelFormat != PixelFormat.Format16bppGrayScale && */ image.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                throw new ArgumentException("Unsupported image format.");
            }

            var info = new RawImageData()
            {
                Resolution = (int)image.HorizontalResolution,
                Width      = image.Width,
                Height     = image.Height,
                PixelDepth = image.PixelFormat == PixelFormat.Format8bppIndexed ? 8 : 16
            };

            var mul = info.PixelDepth == 8 ? 1 : 2;
            var w   = info.Width;
            var h   = info.Height;

            info.Data = new byte[w * h * mul];
            var bmpData = image.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, image.PixelFormat);

            try
            {
                fixed(byte *infoData = info.Data)
                {
                    var dest   = infoData;
                    var source = (byte *)bmpData.Scan0;

                    for (int i = 0; i < h; i++)
                    {
                        NativeMethods.CopyMemory(dest, source, w * mul);
                        dest   += w * mul;
                        source += bmpData.Stride;
                    }
                }
            }
            finally
            {
                image.UnlockBits(bmpData);
            }

            return(info);
        }
Пример #6
0
        //public static unsafe RawImageData WpfImageToImageInfo(BitmapImage image)
        //{
        //    if (image == null) throw new ArgumentException("image");

        //    // 16bpp grayscale is not really supported by the underlying codec.
        //    if (/* image.Format != PixelFormats.Gray16 && */ image.Format != PixelFormats.Gray8)
        //        throw new ArgumentException("Unsupported image format.");

        //    return null;
        //    //if (image.PixelFormat != PixelFormat.Format16bppGrayScale && image.PixelFormat != PixelFormat.Format8bppIndexed)
        //    //    throw new ArgumentException("Unsupported image format.");

        //    //var info = new WsqImageInfo()
        //    //{
        //    //    Resolution = (int)image.HorizontalResolution,
        //    //    Width = image.Width,
        //    //    Height = image.Height,
        //    //    Lossy = true,
        //    //    PixelDepth = image.PixelFormat == PixelFormat.Format8bppIndexed ? 8 : 16
        //    //};

        //    //var mul = info.PixelDepth == 8 ? 1 : 2;
        //    //var w = info.Width;
        //    //var h = info.Height;

        //    //info.Data = new byte[w * h * mul];
        //    //var bmpData = image.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, image.PixelFormat);
        //    //try
        //    //{
        //    //    fixed (byte* infoData = info.Data)
        //    //    {
        //    //        var dest = infoData;
        //    //        var source = (byte*)bmpData.Scan0;
        //    //        for (int i = 0; i < h; i++)
        //    //        {
        //    //            NativeMethods.CopyMemory(dest, source, w * mul);
        //    //            dest += w * mul;
        //    //            source += bmpData.Stride;
        //    //        }
        //    //    }
        //    //}
        //    //finally
        //    //{
        //    //    image.UnlockBits(bmpData);
        //    //}

        //    //return info;
        //}

        public static BitmapSource ImageInfoToWpfImage(RawImageData info)
        {
            const int defaultDpi = 96; // Use this one if resolution not set in the wsq file.

            if (info == null || info.IsEmpty)
            {
                throw new ArgumentException("info");
            }

            // 16bpp grayscale is not really supported by the underlying codec.
            if (info.PixelDepth != 8)
            {
                throw new NotSupportedException(
                          "Source image must have a pixel depth of exactly 8 bpp.");
            }

            var pformat       = PixelFormats.Gray8; // The output pixel format
            var bytesPerPixel = pformat.BitsPerPixel / 8;
            var data          = info.Data;
            var w             = info.Width;
            var h             = info.Height;
            var dpi           = info.Resolution > 0 ? info.Resolution : defaultDpi;
            // Compute the stride
            var stride = w * bytesPerPixel;
            var modulo = stride % 4;

            if (modulo != 0)
            {
                stride += 4 - modulo;
            }

            var pixels = new byte[stride * h * bytesPerPixel]; // The output image data
            // Fill it
            var garbage = stride - w * bytesPerPixel;

            for (var i = 0; i < w * h; i++)
            {
                var y = stride > 0 ? i / w : h - i / w;
                var j = i * bytesPerPixel + y * garbage;
                pixels[j] = data[i];
            }

            return(BitmapSource.Create(w, h, (double)dpi, (double)dpi, pformat, null, pixels, stride));
        }
Пример #7
0
        public static unsafe RawImageData GdiImageToImageInfo(Bitmap image)
        {
            if (image == null) throw new ArgumentException("image");

            // 16bpp grayscale is not really supported by the underlying codec.
            if (/* image.PixelFormat != PixelFormat.Format16bppGrayScale && */ image.PixelFormat != PixelFormat.Format8bppIndexed)
                throw new ArgumentException("Unsupported image format.");

            var info = new RawImageData()
            {
                Resolution = (int)image.HorizontalResolution,
                Width = image.Width,
                Height = image.Height,
                PixelDepth = image.PixelFormat == PixelFormat.Format8bppIndexed ? 8 : 16
            };

            var mul = info.PixelDepth == 8 ? 1 : 2;
            var w = info.Width;
            var h = info.Height;

            info.Data = new byte[w * h * mul];
            var bmpData = image.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, image.PixelFormat);
            try
            {
                fixed (byte* infoData = info.Data)
                {
                    var dest = infoData;
                    var source = (byte*)bmpData.Scan0;
                    for (int i = 0; i < h; i++)
                    {
                        NativeMethods.CopyMemory(dest, source, w * mul);
                        dest += w * mul;
                        source += bmpData.Stride;
                    }
                }
            }
            finally
            {
                image.UnlockBits(bmpData);
            }

            return info;
        }
Пример #8
0
        /// <summary>
        /// Encodes the input image (raw data) to WSQ.
        /// </summary>
        /// <param name="image">The input image.</param>
        /// <param name="bitrate">The bit rate (in bits per pixels).</param>
        /// <param name="comment">An optional comment that is added to the WSQ image.</param>
        /// <returns>WSQ Encoded image.</returns>
        public static byte[] Encode(RawImageData image, float bitrate, string comment)
        {
            if (image == null || image.IsEmpty)
            {
                return(new byte[0]);
            }

            var inputData     = image.Data;
            var inputDataPtr  = Marshal.AllocHGlobal(inputData.Length);
            var outputDataPtr = IntPtr.Zero;

            try
            {
                Marshal.Copy(inputData, 0, inputDataPtr, inputData.Length);

                var outputLength = 0;
                var result       = NativeMethods.wsq_encode(
                    out outputDataPtr, out outputLength, bitrate, inputDataPtr, image.Width, image.Height,
                    image.PixelDepth, image.Resolution, comment ?? string.Empty);

                if (result == 0) // ok
                {
                    var outputData = new byte[outputLength];
                    Marshal.Copy(outputDataPtr, outputData, 0, outputLength);
                    return(outputData);
                }
            }
            finally
            {
                if (inputDataPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(inputDataPtr);
                }
                if (outputDataPtr != IntPtr.Zero)
                {
                    NativeMethods.free_mem(outputDataPtr);
                }
            }

            return(null);
        }
Пример #9
0
        public byte[] EncodeGdi(SD.Bitmap image, float bitrate = WsqCodec.Constants.DefaultBitrate, bool autoConvertToGrayscale = true)
        {
            if (image == null)
            {
                throw new ArgumentNullException("image");
            }

            RawImageData data = null;

            if (autoConvertToGrayscale)
            {
                using (var source = Conversions.To8bppBitmap(image))
                    data = Conversions.GdiImageToImageInfo(source);
            }
            else
            {
                data = Conversions.GdiImageToImageInfo(image);
            }

            return(WsqCodec.Encode(data, bitrate, Comment));
        }
Пример #10
0
 private void LogInfo(RawImageData info, string[] comments = null)
 {
     if (info == null)
         logbox.AppendText("NULL\r\n");
     else if (info.IsEmpty)
         logbox.AppendText("Empty\r\n");
     else
     {
         logbox.AppendText(string.Format("Width  = {0}\r\n", info.Width));
         logbox.AppendText(string.Format("Height = {0}\r\n", info.Height));
         logbox.AppendText(string.Format("Depth  = {0}\r\n", info.PixelDepth));
         logbox.AppendText(string.Format("Dpi    = {0}\r\n", info.Resolution));
         if (comments != null)
         {
             logbox.AppendText("Comments:\r\n");
             var index = 0;
             foreach (var c in comments)
             {
                 logbox.AppendText(string.Format("[{0}]    = {1}\r\n", index, NormalizeComment(c, 9)));
                 index++;
             }
         }
     }
 }
Пример #11
0
 public byte[] Encode(RawImageData image, float bitrate = WsqCodec.Constants.DefaultBitrate)
 {
     return WsqCodec.Encode(image, bitrate, Comment);
 }
Пример #12
0
 public byte[] EncodeCompressionRatio(RawImageData image, float compressionRatio)
 {
     return Encode(image, WsqCodec.CompressionRatioToBitrate(compressionRatio));
 }
Пример #13
0
 public byte[] EncodeQuality(RawImageData image, int quality)
 {
     return EncodeCompressionRatio(image, WsqCodec.QualityToCompressionRatio(quality));
 }
Пример #14
0
 public byte[] Encode(RawImageData image, float bitrate = WsqCodec.Constants.DefaultBitrate)
 {
     return(WsqCodec.Encode(image, bitrate, Comment));
 }
Пример #15
0
 public byte[] EncodeCompressionRatio(RawImageData image, float compressionRatio)
 {
     return(Encode(image, WsqCodec.CompressionRatioToBitrate(compressionRatio)));
 }
Пример #16
0
 public byte[] EncodeQuality(RawImageData image, int quality)
 {
     return(EncodeCompressionRatio(image, WsqCodec.QualityToCompressionRatio(quality)));
 }