/// <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); }
/// <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; }
/// <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; }
/// <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); }