/// <summary> /// Decodes the begin and end byte positions for each quality layer in /// the image /// </summary> /// <returns></returns> public bool DecodeLayerBoundaries() { return(OpenJPEG.DecodeLayerBoundaries(AssetData, out LayerInfo, out Components)); }
private bool DoJ2KDecode(UUID assetID, byte[] j2kData, bool useCSJ2K) { //int DecodeTime = 0; //DecodeTime = Environment.TickCount; OpenJPEG.J2KLayerInfo[] layers; if (!TryLoadCacheForAsset(assetID, out layers)) { if (j2kData == null || j2kData.Length == 0) { // Layer decoding completely failed. Guess at sane defaults for the layer boundaries layers = CreateDefaultLayers(j2kData.Length); // Notify Interested Parties lock (m_notifyList) { if (m_notifyList.ContainsKey(assetID)) { foreach (DecodedCallback d in m_notifyList[assetID].Where(d => d != null)) { d.DynamicInvoke(assetID, layers); } m_notifyList.Remove(assetID); } } return(false); } if (m_useCSJ2K) { try { List <int> layerStarts = J2kImage.GetLayerBoundaries(new MemoryStream(j2kData)); 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 { Start = i == 0 ? 0 : layerStarts[i] }; if (i == layerStarts.Count - 1) { layer.End = j2kData.Length; } else { layer.End = layerStarts[i + 1] - 1; } layers[i] = layer; } } } catch (Exception ex) { MainConsole.Instance.Warn("[J2KDecoderModule]: CSJ2K threw an exception decoding texture " + assetID + ": " + ex.Message); } } else { int components; if (!OpenJPEG.DecodeLayerBoundaries(j2kData, out layers, out components)) { MainConsole.Instance.Warn("[J2KDecoderModule]: OpenJPEG failed to decode texture " + assetID); } } if (layers == null || layers.Length == 0) { if (useCSJ2K == this.m_useCSJ2K) { MainConsole.Instance.Warn("[J2KDecoderModule]: Failed to decode layer data with (" + (m_useCSJ2K ? "CSJ2K" : "OpenJPEG") + ") for texture " + assetID + ", length " + j2kData.Length + " trying " + (!m_useCSJ2K ? "CSJ2K" : "OpenJPEG")); DoJ2KDecode(assetID, j2kData, !m_useCSJ2K); } else { //Second attempt at decode with the other j2k decoder, give up MainConsole.Instance.Warn("[J2KDecoderModule]: Failed to decode layer data (" + (m_useCSJ2K ? "CSJ2K" : "OpenJPEG") + ") for texture " + assetID + ", length " + j2kData.Length + " guessing sane defaults"); // Layer decoding completely failed. Guess at sane defaults for the layer boundaries layers = CreateDefaultLayers(j2kData.Length); // Notify Interested Parties lock (m_notifyList) { if (m_notifyList.ContainsKey(assetID)) { foreach (DecodedCallback d in m_notifyList[assetID].Where(d => d != null)) { d.DynamicInvoke(assetID, layers); } m_notifyList.Remove(assetID); } } return(false); } } else //Don't save the corrupt texture! { // Cache Decoded layers SaveFileCacheForAsset(assetID, layers); } } // Notify Interested Parties lock (m_notifyList) { if (m_notifyList.ContainsKey(assetID)) { foreach (DecodedCallback d in m_notifyList[assetID].Where(d => d != null)) { d.DynamicInvoke(assetID, layers); } m_notifyList.Remove(assetID); } } return(true); }
/// <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); }