Beispiel #1
0
        // encode 
        public static byte[] Encode(libsecondlife.Image image, bool lossless)
        {
            if (
                (image.Channels & ImageChannels.Color) == 0 ||
                ((image.Channels & ImageChannels.Bump) != 0 && (image.Channels & ImageChannels.Alpha) == 0))
                throw new ArgumentException("JPEG2000 encoding is not supported for this channel combination");
            
            MarshalledImage marshalled = new MarshalledImage();

            // allocate and copy to input buffer
            marshalled.width = image.Width;
            marshalled.height = image.Height;
            marshalled.components = 3;
            if ((image.Channels & ImageChannels.Alpha) != 0) marshalled.components++;
            if ((image.Channels & ImageChannels.Bump) != 0) marshalled.components++;

            if (!LibslAllocDecoded(ref marshalled))
                throw new Exception("LibslAllocDecoded failed");

            int n = image.Width * image.Height;

            if ((image.Channels & ImageChannels.Color) != 0)
            {
                Marshal.Copy(image.Red, 0, marshalled.decoded, n);
                Marshal.Copy(image.Green, 0, (IntPtr)(marshalled.decoded.ToInt64() + n), n);
                Marshal.Copy(image.Blue, 0, (IntPtr)(marshalled.decoded.ToInt64() + n * 2), n);
            }

            if ((image.Channels & ImageChannels.Alpha) != 0) Marshal.Copy(image.Alpha, 0, (IntPtr)(marshalled.decoded.ToInt64() + n * 3), n);
            if ((image.Channels & ImageChannels.Bump) != 0) Marshal.Copy(image.Bump, 0, (IntPtr)(marshalled.decoded.ToInt64() + n * 4), n);

            // codec will allocate output buffer
            if (!LibslEncode(ref marshalled, lossless))
                throw new Exception("LibslEncode failed");

            // copy output buffer
            byte[] encoded = new byte[marshalled.length];
            Marshal.Copy(marshalled.encoded, encoded, 0, marshalled.length);

            // free buffers
            LibslFree(ref marshalled);

            return encoded;
        }
Beispiel #2
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="encoded"></param>
        /// <param name="layerInfo"></param>
        /// <param name="components"></param>
        /// <returns></returns>
        public static bool DecodeLayerBoundaries(byte[] encoded, out J2KLayerInfo[] layerInfo, out int components)
        {
            bool success = false;
            layerInfo = null;
            components = 0;
            MarshalledImage marshalled = new MarshalledImage();

            // Allocate and copy to input buffer
            marshalled.length = encoded.Length;
            DotNetAllocEncoded(ref marshalled);
            Marshal.Copy(encoded, 0, marshalled.encoded, encoded.Length);

            // Run the decode
            if (DotNetDecodeWithInfo(ref marshalled))
            {
                components = marshalled.components;

                // Sanity check
                if (marshalled.layers * marshalled.resolutions * marshalled.components == marshalled.packet_count)
                {
                    // Manually marshal the array of opj_packet_info structs
                    MarshalledPacket[] packets = new MarshalledPacket[marshalled.packet_count];
                    int offset = 0;

                    for (int i = 0; i < marshalled.packet_count; i++)
                    {
                        MarshalledPacket packet;
                        packet.start_pos = Marshal.ReadInt32(marshalled.packets, offset);
                        offset += 4;
                        packet.end_ph_pos = Marshal.ReadInt32(marshalled.packets, offset);
                        offset += 4;
                        packet.end_pos = Marshal.ReadInt32(marshalled.packets, offset);
                        offset += 4;
                        // Skip the distortion field. WARNING: It looks like there is alignment
                        // padding in here as well, this needs to be tested on different platforms
                        offset += 12;

                        packets[i] = packet;
                    }

                    layerInfo = new J2KLayerInfo[marshalled.layers];

                    for (int i = 0; i < marshalled.layers; i++)
                    {
                        int packetsPerLayer = marshalled.packet_count / marshalled.layers;
                        MarshalledPacket startPacket = packets[packetsPerLayer * i];
                        MarshalledPacket endPacket = packets[(packetsPerLayer * (i + 1)) - 1];
                        layerInfo[i].Start = startPacket.start_pos;
                        layerInfo[i].End = endPacket.end_pos;
                    }

                    success = true;
                }
                else
                {
                    Logger.Log(String.Format(
                        "Packet count mismatch in JPEG2000 stream. layers={0} resolutions={1} components={2} packets={3}",
                        marshalled.layers, marshalled.resolutions, marshalled.components, marshalled.packet_count),
                        Helpers.LogLevel.Warning);
                }
            }

            DotNetFree(ref marshalled);
            return success;
        }
Beispiel #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="encoded"></param>
        /// <param name="layerInfo"></param>
        /// <param name="components"></param>
        /// <returns></returns>
        public static bool DecodeLayerBoundaries(byte[] encoded, out J2KLayerInfo[] layerInfo, out int components)
        {
            bool success = false;

            layerInfo  = null;
            components = 0;
            MarshalledImage marshalled = new MarshalledImage();

            // Allocate and copy to input buffer
            marshalled.length = encoded.Length;

            lock (OpenJPEGLock)
            {
                if (IntPtr.Size == 8)
                {
                    DotNetAllocEncoded64(ref marshalled);
                }
                else
                {
                    DotNetAllocEncoded(ref marshalled);
                }

                Marshal.Copy(encoded, 0, marshalled.encoded, encoded.Length);

                // Run the decode
                bool decodeSuccess = (IntPtr.Size == 8) ? DotNetDecodeWithInfo64(ref marshalled) : DotNetDecodeWithInfo(ref marshalled);
                if (decodeSuccess)
                {
                    components = marshalled.components;

                    // Sanity check
                    if (marshalled.layers * marshalled.resolutions * marshalled.components == marshalled.packet_count)
                    {
                        // Manually marshal the array of opj_packet_info structs
                        MarshalledPacket[] packets = new MarshalledPacket[marshalled.packet_count];
                        int offset = 0;

                        for (int i = 0; i < marshalled.packet_count; i++)
                        {
                            MarshalledPacket packet;
                            packet.start_pos  = Marshal.ReadInt32(marshalled.packets, offset);
                            offset           += 4;
                            packet.end_ph_pos = Marshal.ReadInt32(marshalled.packets, offset);
                            offset           += 4;
                            packet.end_pos    = Marshal.ReadInt32(marshalled.packets, offset);
                            offset           += 4;
                            //double distortion = (double)Marshal.ReadInt64(marshalled.packets, offset);
                            offset += 8;

                            packets[i] = packet;
                        }

                        layerInfo = new J2KLayerInfo[marshalled.layers];

                        for (int i = 0; i < marshalled.layers; i++)
                        {
                            int packetsPerLayer          = marshalled.packet_count / marshalled.layers;
                            MarshalledPacket startPacket = packets[packetsPerLayer * i];
                            MarshalledPacket endPacket   = packets[(packetsPerLayer * (i + 1)) - 1];
                            layerInfo[i].Start = startPacket.start_pos;
                            layerInfo[i].End   = endPacket.end_pos;
                        }

                        // More sanity checking
                        if (layerInfo.Length == 0 || layerInfo[layerInfo.Length - 1].End <= encoded.Length - 1)
                        {
                            success = true;

                            for (int i = 0; i < layerInfo.Length; i++)
                            {
                                if (layerInfo[i].Start >= layerInfo[i].End ||
                                    (i > 0 && layerInfo[i].Start <= layerInfo[i - 1].End))
                                {
                                    System.Text.StringBuilder output = new System.Text.StringBuilder(
                                        "Inconsistent packet data in JPEG2000 stream:\n");
                                    for (int j = 0; j < layerInfo.Length; j++)
                                    {
                                        output.AppendFormat("Layer {0}: Start: {1} End: {2}\n", j, layerInfo[j].Start, layerInfo[j].End);
                                    }
                                    Logger.DebugLog(output.ToString());

                                    success = false;
                                    break;
                                }
                            }

                            if (!success)
                            {
                                for (int i = 0; i < layerInfo.Length; i++)
                                {
                                    if (i < layerInfo.Length - 1)
                                    {
                                        layerInfo[i].End = layerInfo[i + 1].Start - 1;
                                    }
                                    else
                                    {
                                        layerInfo[i].End = marshalled.length;
                                    }
                                }

                                Logger.DebugLog("Corrected JPEG2000 packet data");
                                success = true;

                                for (int i = 0; i < layerInfo.Length; i++)
                                {
                                    if (layerInfo[i].Start >= layerInfo[i].End ||
                                        (i > 0 && layerInfo[i].Start <= layerInfo[i - 1].End))
                                    {
                                        System.Text.StringBuilder output = new System.Text.StringBuilder(
                                            "Still inconsistent packet data in JPEG2000 stream, giving up:\n");
                                        for (int j = 0; j < layerInfo.Length; j++)
                                        {
                                            output.AppendFormat("Layer {0}: Start: {1} End: {2}\n", j, layerInfo[j].Start, layerInfo[j].End);
                                        }
                                        Logger.DebugLog(output.ToString());

                                        success = false;
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        {
                            Logger.Log(String.Format(
                                           "Last packet end in JPEG2000 stream extends beyond the end of the file. filesize={0} layerend={1}",
                                           encoded.Length, layerInfo[layerInfo.Length - 1].End), Helpers.LogLevel.Warning);
                        }
                    }
                    else
                    {
                        Logger.Log(String.Format(
                                       "Packet count mismatch in JPEG2000 stream. layers={0} resolutions={1} components={2} packets={3}",
                                       marshalled.layers, marshalled.resolutions, marshalled.components, marshalled.packet_count),
                                   Helpers.LogLevel.Warning);
                    }
                }

                if (IntPtr.Size == 8)
                {
                    DotNetFree64(ref marshalled);
                }
                else
                {
                    DotNetFree(ref marshalled);
                }
            }

            return(success);
        }
Beispiel #4
0
 private static extern bool LibslEncode(ref MarshalledImage image, bool lossless);
Beispiel #5
0
 private static extern bool DotNetEncode64(ref MarshalledImage image, bool lossless);
Beispiel #6
0
        /// <summary>
        /// Encode a <seealso cref="ManagedImage"/> object into a byte array
        /// </summary>
        /// <param name="image">The <seealso cref="ManagedImage"/> object to encode</param>
        /// <param name="lossless">true to enable lossless conversion, only useful for small images ie: sculptmaps</param>
        /// <returns>A byte array containing the encoded Image object</returns>
        public static byte[] Encode(ManagedImage image, bool lossless)
        {
            if ((image.Channels & ManagedImage.ImageChannels.Color) == 0 ||
                ((image.Channels & ManagedImage.ImageChannels.Bump) != 0 && (image.Channels & ManagedImage.ImageChannels.Alpha) == 0))
            {
                throw new ArgumentException("JPEG2000 encoding is not supported for this channel combination");
            }

            byte[]          encoded    = null;
            MarshalledImage marshalled = new MarshalledImage();

            // allocate and copy to input buffer
            marshalled.width      = image.Width;
            marshalled.height     = image.Height;
            marshalled.components = 3;
            if ((image.Channels & ManagedImage.ImageChannels.Alpha) != 0)
            {
                marshalled.components++;
            }
            if ((image.Channels & ManagedImage.ImageChannels.Bump) != 0)
            {
                marshalled.components++;
            }

            lock (OpenJPEGLock)
            {
                bool allocSuccess = (IntPtr.Size == 8) ? DotNetAllocDecoded64(ref marshalled) : DotNetAllocDecoded(ref marshalled);

                if (!allocSuccess)
                {
                    throw new Exception("DotNetAllocDecoded failed");
                }

                int n = image.Width * image.Height;

                if ((image.Channels & ManagedImage.ImageChannels.Color) != 0)
                {
                    Marshal.Copy(image.Red, 0, marshalled.decoded, n);
                    Marshal.Copy(image.Green, 0, (IntPtr)(marshalled.decoded.ToInt64() + n), n);
                    Marshal.Copy(image.Blue, 0, (IntPtr)(marshalled.decoded.ToInt64() + n * 2), n);
                }

                if ((image.Channels & ManagedImage.ImageChannels.Alpha) != 0)
                {
                    Marshal.Copy(image.Alpha, 0, (IntPtr)(marshalled.decoded.ToInt64() + n * 3), n);
                }
                if ((image.Channels & ManagedImage.ImageChannels.Bump) != 0)
                {
                    Marshal.Copy(image.Bump, 0, (IntPtr)(marshalled.decoded.ToInt64() + n * 4), n);
                }

                // codec will allocate output buffer
                bool encodeSuccess = (IntPtr.Size == 8) ? DotNetEncode64(ref marshalled, lossless) : DotNetEncode(ref marshalled, lossless);
                if (!encodeSuccess)
                {
                    throw new Exception("DotNetEncode failed");
                }

                // copy output buffer
                encoded = new byte[marshalled.length];
                Marshal.Copy(marshalled.encoded, encoded, 0, marshalled.length);

                // free buffers
                if (IntPtr.Size == 8)
                {
                    DotNetFree64(ref marshalled);
                }
                else
                {
                    DotNetFree(ref marshalled);
                }
            }

            return(encoded);
        }
Beispiel #7
0
 private static extern bool DotNetFree(ref MarshalledImage image);
Beispiel #8
0
 private static extern bool DotNetAllocDecoded64(ref MarshalledImage image);
Beispiel #9
0
        /// <summary>
        /// </summary>
        /// <param name = "encoded"></param>
        /// <param name = "managedImage"></param>
        /// <returns></returns>
        public static bool DecodeToImage(byte[] encoded, out ManagedImage managedImage)
        {
            MarshalledImage marshalled = new MarshalledImage {length = encoded.Length};

            // Allocate and copy to input buffer

            lock (OpenJPEGLock)
            {
                if (IntPtr.Size == 8)
                    DotNetAllocEncoded64(ref marshalled);
                else
                    DotNetAllocEncoded(ref marshalled);

                Marshal.Copy(encoded, 0, marshalled.encoded, encoded.Length);

                // Codec will allocate output buffer
                if (IntPtr.Size == 8)
                    DotNetDecode64(ref marshalled);
                else
                    DotNetDecode(ref marshalled);

                int n = marshalled.width*marshalled.height;

                switch (marshalled.components)
                {
                    case 1: // Grayscale
                        managedImage = new ManagedImage(marshalled.width, marshalled.height,
                                                        ManagedImage.ImageChannels.Color);
                        Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n);
                        Buffer.BlockCopy(managedImage.Red, 0, managedImage.Green, 0, n);
                        Buffer.BlockCopy(managedImage.Red, 0, managedImage.Blue, 0, n);
                        break;

                    case 2: // Grayscale + alpha
                        managedImage = new ManagedImage(marshalled.width, marshalled.height,
                                                        ManagedImage.ImageChannels.Color |
                                                        ManagedImage.ImageChannels.Alpha);
                        Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n);
                        Buffer.BlockCopy(managedImage.Red, 0, managedImage.Green, 0, n);
                        Buffer.BlockCopy(managedImage.Red, 0, managedImage.Blue, 0, n);
                        Marshal.Copy((IntPtr) (marshalled.decoded.ToInt64() + n), managedImage.Alpha, 0, n);
                        break;

                    case 3: // RGB
                        managedImage = new ManagedImage(marshalled.width, marshalled.height,
                                                        ManagedImage.ImageChannels.Color);
                        Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n);
                        Marshal.Copy((IntPtr) (marshalled.decoded.ToInt64() + n), managedImage.Green, 0, n);
                        Marshal.Copy((IntPtr) (marshalled.decoded.ToInt64() + (n*2)), managedImage.Blue, 0, n);
                        break;

                    case 4: // RGBA
                        managedImage = new ManagedImage(marshalled.width, marshalled.height,
                                                        ManagedImage.ImageChannels.Color |
                                                        ManagedImage.ImageChannels.Alpha);
                        Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n);
                        Marshal.Copy((IntPtr) (marshalled.decoded.ToInt64() + n), managedImage.Green, 0, n);
                        Marshal.Copy((IntPtr) (marshalled.decoded.ToInt64() + (n*2)), managedImage.Blue, 0, n);
                        Marshal.Copy((IntPtr) (marshalled.decoded.ToInt64() + (n*3)), managedImage.Alpha, 0, n);
                        break;

                    case 5: // RGBAB
                        managedImage = new ManagedImage(marshalled.width, marshalled.height,
                                                        ManagedImage.ImageChannels.Color |
                                                        ManagedImage.ImageChannels.Alpha |
                                                        ManagedImage.ImageChannels.Bump);
                        Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n);
                        Marshal.Copy((IntPtr) (marshalled.decoded.ToInt64() + n), managedImage.Green, 0, n);
                        Marshal.Copy((IntPtr) (marshalled.decoded.ToInt64() + (n*2)), managedImage.Blue, 0, n);
                        Marshal.Copy((IntPtr) (marshalled.decoded.ToInt64() + (n*3)), managedImage.Alpha, 0, n);
                        Marshal.Copy((IntPtr) (marshalled.decoded.ToInt64() + (n*4)), managedImage.Bump, 0, n);
                        break;

                    default:
                        Logger.Log("Decoded image with unhandled number of components: " + marshalled.components,
                                   Helpers.LogLevel.Error);

                        if (IntPtr.Size == 8)
                            DotNetFree64(ref marshalled);
                        else
                            DotNetFree(ref marshalled);

                        managedImage = null;
                        return false;
                }

                if (IntPtr.Size == 8)
                    DotNetFree64(ref marshalled);
                else
                    DotNetFree(ref marshalled);
            }

            return true;
        }
Beispiel #10
0
 private static extern bool DotNetAllocDecoded(ref MarshalledImage image);
Beispiel #11
0
        /// <summary>
        ///   Encode a <seealso cref = "ManagedImage" /> object into a byte array
        /// </summary>
        /// <param name = "image">The <seealso cref = "ManagedImage" /> object to encode</param>
        /// <param name = "lossless">true to enable lossless conversion, only useful for small images ie: sculptmaps</param>
        /// <returns>A byte array containing the encoded Image object</returns>
        public static byte[] Encode(ManagedImage image, bool lossless)
        {
            if ((image.Channels & ManagedImage.ImageChannels.Color) == 0 ||
                ((image.Channels & ManagedImage.ImageChannels.Bump) != 0 &&
                 (image.Channels & ManagedImage.ImageChannels.Alpha) == 0))
                throw new ArgumentException("JPEG2000 encoding is not supported for this channel combination");

            byte[] encoded = null;
            MarshalledImage marshalled = new MarshalledImage
                                             {width = image.Width, height = image.Height, components = 3};

            // allocate and copy to input buffer
            if ((image.Channels & ManagedImage.ImageChannels.Alpha) != 0) marshalled.components++;
            if ((image.Channels & ManagedImage.ImageChannels.Bump) != 0) marshalled.components++;

            lock (OpenJPEGLock)
            {
                bool allocSuccess = (IntPtr.Size == 8)
                                        ? DotNetAllocDecoded64(ref marshalled)
                                        : DotNetAllocDecoded(ref marshalled);

                if (!allocSuccess)
                    throw new Exception("DotNetAllocDecoded failed");

                int n = image.Width*image.Height;

                if ((image.Channels & ManagedImage.ImageChannels.Color) != 0)
                {
                    Marshal.Copy(image.Red, 0, marshalled.decoded, n);
                    Marshal.Copy(image.Green, 0, (IntPtr) (marshalled.decoded.ToInt64() + n), n);
                    Marshal.Copy(image.Blue, 0, (IntPtr) (marshalled.decoded.ToInt64() + n*2), n);
                }

                if ((image.Channels & ManagedImage.ImageChannels.Alpha) != 0)
                    Marshal.Copy(image.Alpha, 0, (IntPtr) (marshalled.decoded.ToInt64() + n*3), n);
                if ((image.Channels & ManagedImage.ImageChannels.Bump) != 0)
                    Marshal.Copy(image.Bump, 0, (IntPtr) (marshalled.decoded.ToInt64() + n*4), n);

                // codec will allocate output buffer                
                bool encodeSuccess = (IntPtr.Size == 8)
                                         ? DotNetEncode64(ref marshalled, lossless)
                                         : DotNetEncode(ref marshalled, lossless);
                if (!encodeSuccess)
                    throw new Exception("DotNetEncode failed");

                // copy output buffer
                encoded = new byte[marshalled.length];
                Marshal.Copy(marshalled.encoded, encoded, 0, marshalled.length);

                // free buffers
                if (IntPtr.Size == 8)
                    DotNetFree64(ref marshalled);
                else
                    DotNetFree(ref marshalled);
            }

            return encoded;
        }
Beispiel #12
0
 private static extern bool DotNetDecode64(ref MarshalledImage image);
Beispiel #13
0
 private static extern bool DotNetEncode64(ref MarshalledImage image, bool lossless);
Beispiel #14
0
        // encode
        public static byte[] Encode(libsecondlife.Image image, bool lossless)
        {
            if (
                (image.Channels & ImageChannels.Color) == 0 ||
                ((image.Channels & ImageChannels.Bump) != 0 && (image.Channels & ImageChannels.Alpha) == 0))
            {
                throw new ArgumentException("JPEG2000 encoding is not supported for this channel combination");
            }

            MarshalledImage marshalled = new MarshalledImage();

            // allocate and copy to input buffer
            marshalled.width      = image.Width;
            marshalled.height     = image.Height;
            marshalled.components = 3;
            if ((image.Channels & ImageChannels.Alpha) != 0)
            {
                marshalled.components++;
            }
            if ((image.Channels & ImageChannels.Bump) != 0)
            {
                marshalled.components++;
            }

            if (!LibslAllocDecoded(ref marshalled))
            {
                throw new Exception("LibslAllocDecoded failed");
            }

            int n = image.Width * image.Height;

            if ((image.Channels & ImageChannels.Color) != 0)
            {
                Marshal.Copy(image.Red, 0, marshalled.decoded, n);
                Marshal.Copy(image.Green, 0, (IntPtr)(marshalled.decoded.ToInt64() + n), n);
                Marshal.Copy(image.Blue, 0, (IntPtr)(marshalled.decoded.ToInt64() + n * 2), n);
            }

            if ((image.Channels & ImageChannels.Alpha) != 0)
            {
                Marshal.Copy(image.Alpha, 0, (IntPtr)(marshalled.decoded.ToInt64() + n * 3), n);
            }
            if ((image.Channels & ImageChannels.Bump) != 0)
            {
                Marshal.Copy(image.Bump, 0, (IntPtr)(marshalled.decoded.ToInt64() + n * 4), n);
            }

            // codec will allocate output buffer
            if (!LibslEncode(ref marshalled, lossless))
            {
                throw new Exception("LibslEncode failed");
            }

            // copy output buffer
            byte[] encoded = new byte[marshalled.length];
            Marshal.Copy(marshalled.encoded, encoded, 0, marshalled.length);

            // free buffers
            LibslFree(ref marshalled);

            return(encoded);
        }
Beispiel #15
0
 private static extern bool DotNetDecodeWithInfo(ref MarshalledImage image);
Beispiel #16
0
 private static extern bool DotNetDecode(ref MarshalledImage image);
Beispiel #17
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="encoded"></param>
        /// <param name="layerInfo"></param>
        /// <param name="components"></param>
        /// <returns></returns>
        public static bool DecodeLayerBoundaries(byte[] encoded, out J2KLayerInfo[] layerInfo, out int components)
        {
            bool success = false;
            layerInfo = null;
            components = 0;
            MarshalledImage marshalled = new MarshalledImage();

            // Allocate and copy to input buffer
            marshalled.length = encoded.Length;

            lock (OpenJPEGLock)
            {
                DotNetAllocEncoded(ref marshalled);
                Marshal.Copy(encoded, 0, marshalled.encoded, encoded.Length);

                // Run the decode
                if (DotNetDecodeWithInfo(ref marshalled))
                {
                    components = marshalled.components;

                    // Sanity check
                    if (marshalled.layers * marshalled.resolutions * marshalled.components == marshalled.packet_count)
                    {
                        // Manually marshal the array of opj_packet_info structs
                        MarshalledPacket[] packets = new MarshalledPacket[marshalled.packet_count];
                        int offset = 0;

                        for (int i = 0; i < marshalled.packet_count; i++)
                        {
                            MarshalledPacket packet;
                            packet.start_pos = Marshal.ReadInt32(marshalled.packets, offset);
                            offset += 4;
                            packet.end_ph_pos = Marshal.ReadInt32(marshalled.packets, offset);
                            offset += 4;
                            packet.end_pos = Marshal.ReadInt32(marshalled.packets, offset);
                            offset += 4;
                            //double distortion = (double)Marshal.ReadInt64(marshalled.packets, offset);
                            offset += 8;

                            packets[i] = packet;
                        }

                        layerInfo = new J2KLayerInfo[marshalled.layers];

                        for (int i = 0; i < marshalled.layers; i++)
                        {
                            int packetsPerLayer = marshalled.packet_count / marshalled.layers;
                            MarshalledPacket startPacket = packets[packetsPerLayer * i];
                            MarshalledPacket endPacket = packets[(packetsPerLayer * (i + 1)) - 1];
                            layerInfo[i].Start = startPacket.start_pos;
                            layerInfo[i].End = endPacket.end_pos;
                        }

                        // More sanity checking
                        if (layerInfo.Length == 0 || layerInfo[layerInfo.Length - 1].End <= encoded.Length - 1)
                        {
                            success = true;

                            for (int i = 0; i < layerInfo.Length; i++)
                            {
                                if (layerInfo[i].Start >= layerInfo[i].End ||
                                    (i > 0 && layerInfo[i].Start <= layerInfo[i - 1].End))
                                {
                                    System.Text.StringBuilder output = new System.Text.StringBuilder(
                                        "Inconsistent packet data in JPEG2000 stream:\n");
                                    for (int j = 0; j < layerInfo.Length; j++)
                                        output.AppendFormat("Layer {0}: Start: {1} End: {2}\n", j, layerInfo[j].Start, layerInfo[j].End);
                                    Logger.Log(output.ToString(), Helpers.LogLevel.Error);

                                    success = false;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            Logger.Log(String.Format(
                                "Last packet end in JPEG2000 stream extends beyond the end of the file. filesize={0} layerend={1}",
                                encoded.Length, layerInfo[layerInfo.Length - 1].End), Helpers.LogLevel.Warning);
                        }
                    }
                    else
                    {
                        Logger.Log(String.Format(
                            "Packet count mismatch in JPEG2000 stream. layers={0} resolutions={1} components={2} packets={3}",
                            marshalled.layers, marshalled.resolutions, marshalled.components, marshalled.packet_count),
                            Helpers.LogLevel.Warning);
                    }
                }

                DotNetFree(ref marshalled);
            }

            return success;
        }
Beispiel #18
0
 private static extern bool DotNetFree64(ref MarshalledImage image);
Beispiel #19
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="encoded"></param>
        /// <param name="managedImage"></param>
        /// <returns></returns>
        public static bool DecodeToImage(byte[] encoded, out ManagedImage managedImage)
        {
            MarshalledImage marshalled = new MarshalledImage();

            // Allocate and copy to input buffer
            marshalled.length = encoded.Length;
            LibslAllocEncoded(ref marshalled);
            Marshal.Copy(encoded, 0, marshalled.encoded, encoded.Length);

            // Codec will allocate output buffer
            LibslDecode(ref marshalled);

            int n = marshalled.width * marshalled.height;

            switch (marshalled.components)
            {
                case 1: // Grayscale
                    managedImage = new ManagedImage(marshalled.width, marshalled.height,
                        ManagedImage.ImageChannels.Color);
                    Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n);
                    Buffer.BlockCopy(managedImage.Red, 0, managedImage.Green, 0, n);
                    Buffer.BlockCopy(managedImage.Red, 0, managedImage.Blue, 0, n);
                    break;

                case 2: // Grayscale + alpha
                    managedImage = new ManagedImage(marshalled.width, marshalled.height,
                        ManagedImage.ImageChannels.Color | ManagedImage.ImageChannels.Alpha);
                    Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n);
                    Buffer.BlockCopy(managedImage.Red, 0, managedImage.Green, 0, n);
                    Buffer.BlockCopy(managedImage.Red, 0, managedImage.Blue, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)n), managedImage.Alpha, 0, n);
                    break;

                case 3: // RGB
                    managedImage = new ManagedImage(marshalled.width, marshalled.height,
                        ManagedImage.ImageChannels.Color);
                    Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)n), managedImage.Green, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 2)), managedImage.Blue, 0, n);
                    break;

                case 4: // RGBA
                    managedImage = new ManagedImage(marshalled.width, marshalled.height,
                        ManagedImage.ImageChannels.Color | ManagedImage.ImageChannels.Alpha);
                    Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)n), managedImage.Green, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 2)), managedImage.Blue, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 3)), managedImage.Alpha, 0, n);
                    break;

                case 5: // RGBBA
                    managedImage = new ManagedImage(marshalled.width, marshalled.height,
                        ManagedImage.ImageChannels.Color | ManagedImage.ImageChannels.Alpha | ManagedImage.ImageChannels.Bump);
                    Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)n), managedImage.Green, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 2)), managedImage.Blue, 0, n);
                    // Bump comes before alpha in 5 channel encode
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 3)), managedImage.Bump, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 4)), managedImage.Alpha, 0, n);
                    break;

                default:
                    Logger.Log("Decoded image with unhandled number of components: " + marshalled.components,
                        Helpers.LogLevel.Error);
                    LibslFree(ref marshalled);
                    managedImage = null;
                    return false;
            }

            LibslFree(ref marshalled);
            return true;
        }
Beispiel #20
0
 private static extern bool DotNetDecodeWithInfo64(ref MarshalledImage image);
Beispiel #21
0
        public static libsecondlife.Image Decode(byte[] encoded)
        {
            MarshalledImage marshalled = new MarshalledImage();

            // allocate and copy to input buffer
            marshalled.length = encoded.Length;
            LibslAllocEncoded(ref marshalled);
            Marshal.Copy(encoded, 0, marshalled.encoded, encoded.Length);

            // codec will allocate output buffer
            LibslDecode(ref marshalled);

            libsecondlife.Image image;
            int n = marshalled.width * marshalled.height;

            switch (marshalled.components)
            {
            case 1:     // grayscale
                image = new libsecondlife.Image(marshalled.width, marshalled.height, ImageChannels.Color);
                Marshal.Copy(marshalled.decoded, image.Red, 0, n);
                Array.Copy(image.Red, image.Green, n);
                Array.Copy(image.Red, image.Blue, n);
                break;

            case 2:     // grayscale + alpha
                image = new libsecondlife.Image(marshalled.width, marshalled.height, ImageChannels.Color | ImageChannels.Alpha);
                Marshal.Copy(marshalled.decoded, image.Red, 0, n);
                Array.Copy(image.Red, image.Green, n);
                Array.Copy(image.Red, image.Blue, n);
                Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n), image.Alpha, 0, n);
                break;

            case 3:     // RGB
                image = new libsecondlife.Image(marshalled.width, marshalled.height, ImageChannels.Color);
                Marshal.Copy(marshalled.decoded, image.Red, 0, n);
                Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n), image.Green, 0, n);
                Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n * 2), image.Blue, 0, n);
                break;

            case 4:     // RGBA
                image = new libsecondlife.Image(marshalled.width, marshalled.height, ImageChannels.Color | ImageChannels.Alpha);
                Marshal.Copy(marshalled.decoded, image.Red, 0, n);
                Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n), image.Green, 0, n);
                Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n * 2), image.Blue, 0, n);
                Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n * 3), image.Alpha, 0, n);
                break;

            case 5:     // RGBBA
                image = new libsecondlife.Image(marshalled.width, marshalled.height, ImageChannels.Color | ImageChannels.Alpha | ImageChannels.Bump);
                Marshal.Copy(marshalled.decoded, image.Red, 0, n);
                Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n), image.Green, 0, n);
                Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n * 2), image.Blue, 0, n);
                Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n * 3), image.Bump, 0, n);     // bump comes before alpha in 5 channel encode
                Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n * 4), image.Alpha, 0, n);
                break;

            default:
                throw new Exception("Decoded image with unhandled number of components (" + marshalled.components + ")");
            }

            // free buffers
            LibslFree(ref marshalled);

            return(image);
        }
Beispiel #22
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="encoded"></param>
        /// <param name="managedImage"></param>
        /// <returns></returns>
        public static bool DecodeToImage(byte[] encoded, out ManagedImage managedImage)
        {
            MarshalledImage marshalled = new MarshalledImage();

            // Allocate and copy to input buffer
            marshalled.length = encoded.Length;

            lock (OpenJPEGLock)
            {
                if (IntPtr.Size == 8)
                {
                    DotNetAllocEncoded64(ref marshalled);
                }
                else
                {
                    DotNetAllocEncoded(ref marshalled);
                }

                Marshal.Copy(encoded, 0, marshalled.encoded, encoded.Length);

                // Codec will allocate output buffer
                if (IntPtr.Size == 8)
                {
                    DotNetDecode64(ref marshalled);
                }
                else
                {
                    DotNetDecode(ref marshalled);
                }

                int n = marshalled.width * marshalled.height;

                switch (marshalled.components)
                {
                case 1:     // Grayscale
                    managedImage = new ManagedImage(marshalled.width, marshalled.height,
                                                    ManagedImage.ImageChannels.Color);
                    Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n);
                    Buffer.BlockCopy(managedImage.Red, 0, managedImage.Green, 0, n);
                    Buffer.BlockCopy(managedImage.Red, 0, managedImage.Blue, 0, n);
                    break;

                case 2:     // Grayscale + alpha
                    managedImage = new ManagedImage(marshalled.width, marshalled.height,
                                                    ManagedImage.ImageChannels.Color | ManagedImage.ImageChannels.Alpha);
                    Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n);
                    Buffer.BlockCopy(managedImage.Red, 0, managedImage.Green, 0, n);
                    Buffer.BlockCopy(managedImage.Red, 0, managedImage.Blue, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)n), managedImage.Alpha, 0, n);
                    break;

                case 3:     // RGB
                    managedImage = new ManagedImage(marshalled.width, marshalled.height,
                                                    ManagedImage.ImageChannels.Color);
                    Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)n), managedImage.Green, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 2)), managedImage.Blue, 0, n);
                    break;

                case 4:     // RGBA
                    managedImage = new ManagedImage(marshalled.width, marshalled.height,
                                                    ManagedImage.ImageChannels.Color | ManagedImage.ImageChannels.Alpha);
                    Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)n), managedImage.Green, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 2)), managedImage.Blue, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 3)), managedImage.Alpha, 0, n);
                    break;

                case 5:     // RGBAB
                    managedImage = new ManagedImage(marshalled.width, marshalled.height,
                                                    ManagedImage.ImageChannels.Color | ManagedImage.ImageChannels.Alpha | ManagedImage.ImageChannels.Bump);
                    Marshal.Copy(marshalled.decoded, managedImage.Red, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)n), managedImage.Green, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 2)), managedImage.Blue, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 3)), managedImage.Alpha, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + (long)(n * 4)), managedImage.Bump, 0, n);
                    break;

                default:
                    Logger.Log("Decoded image with unhandled number of components: " + marshalled.components,
                               Helpers.LogLevel.Error);

                    if (IntPtr.Size == 8)
                    {
                        DotNetFree64(ref marshalled);
                    }
                    else
                    {
                        DotNetFree(ref marshalled);
                    }

                    managedImage = null;
                    return(false);
                }

                if (IntPtr.Size == 8)
                {
                    DotNetFree64(ref marshalled);
                }
                else
                {
                    DotNetFree(ref marshalled);
                }
            }

            return(true);
        }
Beispiel #23
0
 private static extern bool LibslAllocDecoded(ref MarshalledImage image);
Beispiel #24
0
 private static extern bool LibslAllocDecoded(ref MarshalledImage image);
Beispiel #25
0
 private static extern bool LibslEncode(ref MarshalledImage image, bool lossless);
Beispiel #26
0
 private static extern bool LibslDecode(ref MarshalledImage image);
Beispiel #27
0
 private static extern bool LibslDecode(ref MarshalledImage image);
Beispiel #28
0
        public static libsecondlife.Image Decode(byte[] encoded)
        {
            MarshalledImage marshalled = new MarshalledImage();

            // allocate and copy to input buffer
            marshalled.length = encoded.Length;
            LibslAllocEncoded(ref marshalled);
            Marshal.Copy(encoded, 0, marshalled.encoded, encoded.Length);

            // codec will allocate output buffer
            LibslDecode(ref marshalled);

            libsecondlife.Image image;
            int n = marshalled.width * marshalled.height;

            switch (marshalled.components)
            {
                case 1: // grayscale
                    image = new libsecondlife.Image(marshalled.width, marshalled.height, ImageChannels.Color);
                    Marshal.Copy(marshalled.decoded, image.Red, 0, n);
                    Array.Copy(image.Red, image.Green, n);
                    Array.Copy(image.Red, image.Blue, n);
                    break;

                case 2: // grayscale + alpha
                    image = new libsecondlife.Image(marshalled.width, marshalled.height, ImageChannels.Color | ImageChannels.Alpha);
                    Marshal.Copy(marshalled.decoded, image.Red, 0, n);
                    Array.Copy(image.Red, image.Green, n);
                    Array.Copy(image.Red, image.Blue, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n), image.Alpha, 0, n);
                    break;

                case 3: // RGB
                    image = new libsecondlife.Image(marshalled.width, marshalled.height, ImageChannels.Color);
                    Marshal.Copy(marshalled.decoded, image.Red, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n), image.Green, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n * 2), image.Blue, 0, n);
                    break;

                case 4: // RGBA
                    image = new libsecondlife.Image(marshalled.width, marshalled.height, ImageChannels.Color | ImageChannels.Alpha);
                    Marshal.Copy(marshalled.decoded, image.Red, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n), image.Green, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n * 2), image.Blue, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n * 3), image.Alpha, 0, n);
                    break;

                case 5: // RGBBA
                    image = new libsecondlife.Image(marshalled.width, marshalled.height, ImageChannels.Color | ImageChannels.Alpha | ImageChannels.Bump);
                    Marshal.Copy(marshalled.decoded, image.Red, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n), image.Green, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n * 2), image.Blue, 0, n);
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n * 3), image.Bump, 0, n); // bump comes before alpha in 5 channel encode
                    Marshal.Copy((IntPtr)(marshalled.decoded.ToInt64() + n * 4), image.Alpha, 0, n);
                    break;

                default:
                    throw new Exception("Decoded image with unhandled number of components (" + marshalled.components + ")");
            }

            // free buffers
            LibslFree(ref marshalled);

            return image;
        }
Beispiel #29
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="encoded"></param>
        /// <param name="layerInfo"></param>
        /// <param name="components"></param>
        /// <returns></returns>
        public static bool DecodeLayerBoundaries(byte[] encoded, out J2KLayerInfo[] layerInfo, out int components)
        {
            bool success = false;

            layerInfo  = null;
            components = 0;
            MarshalledImage marshalled = new MarshalledImage();

            // Allocate and copy to input buffer
            marshalled.length = encoded.Length;
            DotNetAllocEncoded(ref marshalled);
            Marshal.Copy(encoded, 0, marshalled.encoded, encoded.Length);

            // Run the decode
            if (DotNetDecodeWithInfo(ref marshalled))
            {
                components = marshalled.components;

                // Sanity check
                if (marshalled.layers * marshalled.resolutions * marshalled.components == marshalled.packet_count)
                {
                    // Manually marshal the array of opj_packet_info structs
                    MarshalledPacket[] packets = new MarshalledPacket[marshalled.packet_count];
                    int offset = 0;

                    for (int i = 0; i < marshalled.packet_count; i++)
                    {
                        MarshalledPacket packet;
                        packet.start_pos  = Marshal.ReadInt32(marshalled.packets, offset);
                        offset           += 4;
                        packet.end_ph_pos = Marshal.ReadInt32(marshalled.packets, offset);
                        offset           += 4;
                        packet.end_pos    = Marshal.ReadInt32(marshalled.packets, offset);
                        offset           += 4;
                        // Skip the distortion field. WARNING: It looks like there is alignment
                        // padding in here as well, this needs to be tested on different platforms
                        offset += 12;

                        packets[i] = packet;
                    }

                    layerInfo = new J2KLayerInfo[marshalled.layers];

                    for (int i = 0; i < marshalled.layers; i++)
                    {
                        int packetsPerLayer          = marshalled.packet_count / marshalled.layers;
                        MarshalledPacket startPacket = packets[packetsPerLayer * i];
                        MarshalledPacket endPacket   = packets[(packetsPerLayer * (i + 1)) - 1];
                        layerInfo[i].Start = startPacket.start_pos;
                        layerInfo[i].End   = endPacket.end_pos;
                    }

                    success = true;
                }
                else
                {
                    Logger.Log(String.Format(
                                   "Packet count mismatch in JPEG2000 stream. layers={0} resolutions={1} components={2} packets={3}",
                                   marshalled.layers, marshalled.resolutions, marshalled.components, marshalled.packet_count),
                               Helpers.LogLevel.Warning);
                }
            }

            DotNetFree(ref marshalled);
            return(success);
        }