/// <summary> /// Save Layers to Disk Cache /// </summary> /// <param name="AssetId">Asset to Save the layers. Used int he file name by default</param> /// <param name="Layers">The Layer Data from OpenJpeg</param> /// <returns></returns> public bool SaveCacheForAsset(UUID AssetId, OpenJPEG.J2KLayerInfo[] Layers) { if (Layers.Length > 0) { m_decodedCache.AddOrUpdate(AssetId, Layers, TimeSpan.FromMinutes(10)); if (enabled == true) { using (FileStream fsCache = new FileStream(String.Format("{0}/{1}", m_cacheDecodeFolder, FileNameFromAssetId(AssetId)), FileMode.Create)) { using (StreamWriter fsSWCache = new StreamWriter(fsCache)) { StringBuilder stringResult = new StringBuilder(); string strEnd = "\n"; for (int i = 0; i < Layers.Length; i++) { if (i == (Layers.Length - 1)) strEnd = String.Empty; stringResult.AppendFormat("{0}|{1}|{2}{3}", Layers[i].Start, Layers[i].End, Layers[i].End - Layers[i].Start, strEnd); } fsSWCache.Write(stringResult.ToString()); fsSWCache.Close(); return true; } } } } return false; }
bool TryLoadCacheForAsset(UUID assetId, out OpenJPEG.J2KLayerInfo[] layers) { if (m_decodedCache.TryGetValue(assetId, out layers)) { return true; } else if (m_cache != null) { string assetName = "j2kCache_" + assetId; AssetBase layerDecodeAsset = m_cache.Get(assetName); if (layerDecodeAsset != null) { #region Deserialize Layer Data string readResult = Util.UTF8.GetString(layerDecodeAsset.Data); string[] lines = readResult.Split(new[] {'\n'}, StringSplitOptions.RemoveEmptyEntries); if (lines.Length == 0) { MainConsole.Instance.Warn("[J2KDecodeCache]: Expiring corrupted layer data (empty) " + assetName); m_cache.Expire(assetName); return false; } layers = new OpenJPEG.J2KLayerInfo[lines.Length]; for (int i = 0; i < lines.Length; i++) { string[] elements = lines[i].Split('|'); if (elements.Length == 3) { int element1, element2; try { element1 = Convert.ToInt32(elements[0]); element2 = Convert.ToInt32(elements[1]); } catch (FormatException) { MainConsole.Instance.Warn("[J2KDecodeCache]: Expiring corrupted layer data (format) " + assetName); m_cache.Expire(assetName); return false; } layers[i] = new OpenJPEG.J2KLayerInfo {Start = element1, End = element2}; } else { MainConsole.Instance.Warn("[J2KDecodeCache]: Expiring corrupted layer data (layout) " + assetName); m_cache.Expire(assetName); return false; } } #endregion Deserialize Layer Data return true; } } return false; }
void SaveFileCacheForAsset(UUID assetId, OpenJPEG.J2KLayerInfo[] layers) { if (m_useCache) m_decodedCache.AddOrUpdate(assetId, layers, TimeSpan.FromMinutes(10)); if (m_cache != null) { string assetID = "j2kCache_" + assetId; AssetBase layerDecodeAsset = new AssetBase(assetID, assetID, AssetType.Notecard, UUID.Zero) {Flags = AssetFlags.Local | AssetFlags.Temporary}; #region Serialize Layer Data StringBuilder stringResult = new StringBuilder(); string strEnd = "\n"; for (int i = 0; i < layers.Length; i++) { if (i == layers.Length - 1) strEnd = string.Empty; stringResult.AppendFormat("{0}|{1}|{2}{3}", layers[i].Start, layers[i].End, layers[i].End - layers[i].Start, strEnd); } layerDecodeAsset.Data = Util.UTF8.GetBytes(stringResult.ToString()); #endregion Serialize Layer Data m_cache.Cache(assetID, layerDecodeAsset); } }
private void SaveFileCacheForAsset(UUID AssetId, OpenJPEG.J2KLayerInfo[] Layers) { m_decodedCache.AddOrUpdate(AssetId, Layers, TimeSpan.FromMinutes(10)); if (m_cache != null) { string assetID = "j2kCache_" + AssetId.ToString(); AssetBase layerDecodeAsset = new AssetBase(assetID, assetID, (sbyte)AssetType.Notecard, m_scene.RegionInfo.RegionID.ToString()); layerDecodeAsset.Local = true; layerDecodeAsset.Temporary = true; #region Serialize Layer Data StringBuilder stringResult = new StringBuilder(); string strEnd = "\n"; for (int i = 0; i < Layers.Length; i++) { if (i == Layers.Length - 1) strEnd = String.Empty; stringResult.AppendFormat("{0}|{1}|{2}{3}", Layers[i].Start, Layers[i].End, Layers[i].End - Layers[i].Start, strEnd); } layerDecodeAsset.Data = Util.UTF8.GetBytes(stringResult.ToString()); #endregion Serialize Layer Data m_cache.Cache(layerDecodeAsset); } }
private void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers) { m_layers = layers; IsDecoded = true; RunUpdate(); }
/// <summary> /// Decode Jpeg2000 Asset Data /// </summary> /// <param name="assetID">UUID of Asset</param> /// <param name="j2kData">JPEG2000 data</param> /// <param name="layers">layer data</param> /// <param name="components">number of components</param> /// <returns>true if decode was successful. false otherwise.</returns> private bool DoJ2KDecode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers, out int components) { // m_log.DebugFormat( // "[J2KDecoderModule]: Doing J2K decoding of {0} bytes for asset {1}", j2kData.Length, assetID); bool decodedSuccessfully = true; //int DecodeTime = 0; //DecodeTime = Environment.TickCount; // We don't get this from CSJ2K. Is it relevant? components = 0; if (!TryLoadCacheForAsset(assetID, out layers)) { if (m_useCSJ2K) { try { List<int> layerStarts; using (MemoryStream ms = new MemoryStream(j2kData)) { layerStarts = CSJ2K.J2kImage.GetLayerBoundaries(ms); } if (layerStarts != null && layerStarts.Count > 0) { layers = new OpenJPEG.J2KLayerInfo[layerStarts.Count]; for (int i = 0; i < layerStarts.Count; i++) { OpenJPEG.J2KLayerInfo layer = new OpenJPEG.J2KLayerInfo(); if (i == 0) layer.Start = 0; else layer.Start = layerStarts[i]; if (i == layerStarts.Count - 1) layer.End = j2kData.Length; else layer.End = layerStarts[i + 1] - 1; layers[i] = layer; } } } catch (Exception ex) { m_log.Warn("[J2KDecoderModule]: CSJ2K threw an exception decoding texture " + assetID + ": " + ex.Message); decodedSuccessfully = false; } } else { if (!OpenJPEG.DecodeLayerBoundaries(j2kData, out layers, out components)) { m_log.Warn("[J2KDecoderModule]: OpenJPEG failed to decode texture " + assetID); decodedSuccessfully = false; } } if (layers == null || layers.Length == 0) { m_log.Warn("[J2KDecoderModule]: Failed to decode layer data for texture " + assetID + ", guessing sane defaults"); // Layer decoding completely failed. Guess at sane defaults for the layer boundaries layers = CreateDefaultLayers(j2kData.Length); decodedSuccessfully = false; } // Cache Decoded layers SaveFileCacheForAsset(assetID, layers); } // Notify Interested Parties lock (m_notifyList) { if (m_notifyList.ContainsKey(assetID)) { foreach (DecodedCallback d in m_notifyList[assetID]) { if (d != null) d.DynamicInvoke(assetID, layers); } m_notifyList.Remove(assetID); } } return decodedSuccessfully; }
public bool Decode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers, out int components) { return DoJ2KDecode(assetID, j2kData, out layers, out components); }
/// <summary> /// Decode Jpeg2000 Asset Data /// </summary> /// <param name="assetID">UUID of Asset</param> /// <param name="j2kData">JPEG2000 data</param> /// <param name="layers">layer data</param> /// <param name="components">number of components</param> /// <returns>true if decode was successful. false otherwise.</returns> private bool DoJ2KDecode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers) { bool decodedSuccessfully = true; int DecodeTime = Environment.TickCount; layers = new OpenJPEG.J2KLayerInfo[0]; // Dummy result for if it fails. Informs that there's only full quality try { using (MemoryStream ms = new MemoryStream(j2kData)) { List<int> layerStarts = CSJ2K.J2kImage.GetLayerBoundaries(ms); if (layerStarts != null && layerStarts.Count > 0) { layers = new OpenJPEG.J2KLayerInfo[layerStarts.Count]; for (int i = 0; i < layerStarts.Count; i++) { OpenJPEG.J2KLayerInfo layer = new OpenJPEG.J2KLayerInfo(); if (i == 0) layer.Start = 0; else layer.Start = layerStarts[i]; if (i == layerStarts.Count - 1) layer.End = j2kData.Length; else layer.End = layerStarts[i + 1] - 1; layers[i] = layer; } } } } catch (Exception ex) { m_log.Warn("[J2KDecoderModule]: CSJ2K threw an exception decoding texture " + assetID + ": " + ex.Message); decodedSuccessfully = false; } if (layers.Length == 0) { m_log.Warn("[J2KDecoderModule]: Failed to decode layer data for texture " + assetID + ", guessing sane defaults"); // Layer decoding completely failed. Guess at sane defaults for the layer boundaries layers = CreateDefaultLayers(j2kData.Length); decodedSuccessfully = false; } else { int elapsed = Environment.TickCount - DecodeTime; if (elapsed >= 50) m_log.InfoFormat("[J2KDecoderModule]: {0} Decode Time: {1}", elapsed, assetID); // Cache Decoded layers fCache.SaveCacheForAsset(assetID, layers); } return decodedSuccessfully; }
/// <summary> /// Loads the Layer data from the disk cache /// Returns true if load succeeded /// </summary> /// <param name="AssetId">AssetId that we're checking the cache for</param> /// <param name="Layers">out layers to save to</param> /// <returns>true if load succeeded</returns> public bool TryLoadCacheForAsset(UUID AssetId, out OpenJPEG.J2KLayerInfo[] Layers) { // Check if it's cached in memory if (m_decodedCache.TryGetValue(AssetId, out Layers)) { return true; } // Look for it in the file cache string filename = String.Format("{0}/{1}", m_cacheDecodeFolder, FileNameFromAssetId(AssetId)); Layers = new OpenJPEG.J2KLayerInfo[0]; if ((File.Exists(filename) == false) || (enabled == false)) return false; string readResult = String.Empty; try { using (FileStream fsCachefile = new FileStream(filename, FileMode.Open)) { using (StreamReader sr = new StreamReader(fsCachefile)) { readResult = sr.ReadToEnd(); sr.Close(); } } } catch (IOException ioe) { if (ioe is PathTooLongException) { m_log.Error( "[J2KDecodeCache]: Cache Read failed. Path is too long."); } else if (ioe is DirectoryNotFoundException) { m_log.Error( "[J2KDecodeCache]: Cache Read failed. Cache Directory does not exist!"); enabled = false; } else { m_log.Error( "[J2KDecodeCache]: Cache Read failed. IO Exception."); } return false; } catch (UnauthorizedAccessException) { m_log.Error( "[J2KDecodeCache]: Cache Read failed. UnauthorizedAccessException Exception. Do you have the proper permissions on this file?"); return false; } catch (ArgumentException ae) { if (ae is ArgumentNullException) { m_log.Error( "[J2KDecodeCache]: Cache Read failed. No Filename provided"); } else { m_log.Error( "[J2KDecodeCache]: Cache Read failed. Filname was invalid"); } return false; } catch (NotSupportedException) { m_log.Error( "[J2KDecodeCache]: Cache Read failed, not supported. Cache disabled!"); enabled = false; return false; } catch (Exception e) { m_log.ErrorFormat( "[J2KDecodeCache]: Cache Read failed, unknown exception. Error: {0}", e.ToString()); return false; } string[] lines = readResult.Split('\n'); if (lines.Length <= 0) return false; Layers = new OpenJPEG.J2KLayerInfo[lines.Length]; for (int i = 0; i < lines.Length; i++) { string[] elements = lines[i].Split('|'); if (elements.Length == 3) { int element1, element2; try { element1 = Convert.ToInt32(elements[0]); element2 = Convert.ToInt32(elements[1]); } catch (FormatException) { m_log.WarnFormat("[J2KDecodeCache]: Cache Read failed with ErrorConvert for {0}", AssetId); Layers = new OpenJPEG.J2KLayerInfo[0]; return false; } Layers[i] = new OpenJPEG.J2KLayerInfo(); Layers[i].Start = element1; Layers[i].End = element2; } else { // reading failed m_log.WarnFormat("[J2KDecodeCache]: Cache Read failed for {0}", AssetId); Layers = new OpenJPEG.J2KLayerInfo[0]; return false; } } return true; }
public bool Decode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers) { bool decodedSuccessfully = true; lock (fCache) { decodedSuccessfully = fCache.TryLoadCacheForAsset(assetID, out layers); } if (!decodedSuccessfully) decodedSuccessfully = DoJ2KDecode(assetID, j2kData, out layers); // Notify Interested Parties lock (m_notifyList) { if (m_notifyList.ContainsKey(assetID)) { foreach (DecodedCallback d in m_notifyList[assetID]) { if (d != null) d.DynamicInvoke(assetID, layers); } m_notifyList.Remove(assetID); } } return (decodedSuccessfully); }
/// <summary> /// Save Layers to Disk Cache /// </summary> /// <param name="AssetId">Asset to Save the layers. Used int he file name by default</param> /// <param name="Layers">The Layer Data from OpenJpeg</param> /// <returns></returns> public bool SaveFileCacheForAsset(UUID AssetId, OpenJPEG.J2KLayerInfo[] Layers) { if (Layers.Length > 0 && enabled) { FileStream fsCache = new FileStream(String.Format("{0}/{1}", m_cacheDecodeFolder, FileNameFromAssetId(AssetId)), FileMode.Create); StreamWriter fsSWCache = new StreamWriter(fsCache); StringBuilder stringResult = new StringBuilder(); string strEnd = "\n"; for (int i = 0; i < Layers.Length; i++) { if (i == (Layers.Length - 1)) strEnd = ""; stringResult.AppendFormat("{0}|{1}|{2}{3}", Layers[i].Start, Layers[i].End, Layers[i].End - Layers[i].Start, strEnd); } fsSWCache.Write(stringResult.ToString()); fsSWCache.Close(); fsSWCache.Dispose(); fsCache.Dispose(); return true; } return false; }
/// <summary> /// Decode Jpeg2000 Asset Data /// </summary> /// <param name="AssetId">UUID of Asset</param> /// <param name="j2kdata">Byte Array Asset Data </param> private bool DoJ2KDecode(UUID assetID, byte[] j2kdata, out OpenJPEG.J2KLayerInfo[] layers) { int DecodeTime = 0; DecodeTime = Environment.TickCount; bool decodedSuccessfully = true; layers = new OpenJPEG.J2KLayerInfo[0]; // Dummy result for if it fails. Informs that there's only full quality try { AssetTexture texture = new AssetTexture(assetID, j2kdata); bool sane = false; if (texture.DecodeLayerBoundaries()) { sane = true; // Sanity check all of the layers for (int i = 0; i < texture.LayerInfo.Length; i++) { if (texture.LayerInfo[i].End > texture.AssetData.Length) { sane = false; break; } } } if (sane) { m_log.InfoFormat("[J2KDecoderModule]: {0} Decode Time: {1}", Environment.TickCount - DecodeTime, assetID); layers = texture.LayerInfo; } else { m_log.Warn("[J2KDecoderModule]: Failed to decode layer data for texture " + assetID + ", guessing sane defaults"); decodedSuccessfully = false; // Layer decoding completely failed. Guess at sane defaults for the layer boundaries layers = CreateDefaultLayers(j2kdata.Length); } fCache.SaveCacheForAsset(assetID, layers); texture = null; // dereference and dispose of ManagedImage } catch (DllNotFoundException) { m_log.Error( "[J2KDecoderModule]: OpenJpeg is not installed properly. Decoding disabled! This will slow down texture performance! Often times this is because of an old version of GLIBC. You must have version 2.4 or above!"); OpenJpegFail = true; decodedSuccessfully = false; } catch (Exception ex) { m_log.WarnFormat( "[J2KDecoderModule]: JPEG2000 texture decoding threw an exception for {0}, {1}", assetID, ex); decodedSuccessfully = false; } return (decodedSuccessfully); }
public bool Decode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers) { bool decodedSuccessfully = true; layers = new OpenJPEG.J2KLayerInfo[0]; // Dummy result for if it fails. Informs that there's only full quality if (! OpenJpegFail) { lock (fCache) { decodedSuccessfully = fCache.TryLoadCacheForAsset(assetID, out layers); } if (!decodedSuccessfully) decodedSuccessfully = DoJ2KDecode(assetID, j2kData, out layers); } // Notify Interested Parties lock (m_notifyList) { if (m_notifyList.ContainsKey(assetID)) { foreach (DecodedCallback d in m_notifyList[assetID]) { if (d != null) d.DynamicInvoke(assetID, layers); } m_notifyList.Remove(assetID); } } return (decodedSuccessfully); }
public void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers) { m_image.m_outstandingtextures++; Layers = layers; m_decoded = true; RunUpdate(); }