void pipeline_OnDownloadFinished(UUID id, bool success) { ImageDownload download; if (currentDownloads.TryGetValue(id, out download)) { lock (currentDownloads) currentDownloads.Remove(id); if (success) { // Set the texture to the downloaded texture data AssetTexture texture = new AssetTexture(id, Pipeline.GetTextureToRender(id).AssetData); download.Texture = texture; Pipeline.RemoveFromPipeline(id); // Store this texture in the local asset store for later server.Assets.StoreAsset(texture); SendTexture(download.Agent, download.Texture, download.DiscardLevel, download.CurrentPacket, download.Priority); } else { Logger.Log("[Periscope] Failed to download texture " + id.ToString(), Helpers.LogLevel.Warning); ImageNotInDatabasePacket notfound = new ImageNotInDatabasePacket(); notfound.ImageID.ID = id; server.UDP.SendPacket(download.Agent.Avatar.ID, notfound, PacketCategory.Texture); } } else { Logger.Log("[Periscope] Pipeline downloaded a texture we're not tracking, " + id.ToString(), Helpers.LogLevel.Warning); } }
public static void ImageDecompress(AssetBase assetBase) { if (assetBase == null) return; AssetType type = (AssetType)assetBase.Type; AssetTexture texture = null; switch(type) { case AssetType.ImageJPEG: case AssetType.ImageTGA: case AssetType.Texture: // Jpeg2000 case AssetType.TextureTGA: texture = new AssetTexture(new UUID(assetBase.ID), assetBase.Data); break; } if (texture == null) return; if (type == AssetType.Texture) { try { if (texture.Decode()) assetBase.Data = texture.Image.ExportTGA(); } catch { } } }
private void Assets_OnImageReceived(ImageDownload image, AssetTexture asset) { Image = image; Asset = asset; DownloadHandle.Set(); }
public override string Execute(string[] args, UUID fromAgentID) { if (args.Length != 1 && args.Length != 2) return "Usage: downloadtexture [texture-uuid] [discardlevel]"; TextureID = UUID.Zero; DownloadHandle.Reset(); Image = null; Asset = null; if (UUID.TryParse(args[0], out TextureID)) { int discardLevel = 0; if (args.Length > 1) { if (!Int32.TryParse(args[1], out discardLevel)) return "Usage: downloadtexture [texture-uuid] [discardlevel]"; } Client.Assets.RequestImage(TextureID, ImageType.Normal, 1000000.0f, discardLevel, 0); if (DownloadHandle.WaitOne(120 * 1000, false)) { if (Image != null && Image.Success) { if (Asset != null && Asset.Decode()) { try { File.WriteAllBytes(Image.ID.ToString() + ".jp2", Asset.AssetData); } catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client, ex); } return String.Format("Saved {0}.jp2 ({1}x{2})", Image.ID, Asset.Image.Width, Asset.Image.Height); } else { return "Failed to decode texture " + TextureID.ToString(); } } else if (Image != null && Image.NotFound) { return "Simulator reported texture not found: " + TextureID.ToString(); } else { return "Download failed for texture " + TextureID.ToString(); } } else { return "Timed out waiting for texture download"; } } else { return "Usage: downloadtexture [texture-uuid]"; } }
private void Assets_OnImageReceived(ImageDownload image, AssetTexture asset) { if (enabled && alreadyRequested.ContainsKey(image.ID)) { if (image.Success) Logger.DebugLog(String.Format("Finished downloading texture {0} ({1} bytes)", image.ID, image.Size)); else Logger.Log("Failed to download texture " + image.ID.ToString(), Helpers.LogLevel.Warning); } }
void Assets_OnImageReceived(ImageDownload image, AssetTexture assetTexture) { ManagedImage imgData; Image bitmap; if (image.Success) { OpenJPEG.DecodeToImage(image.AssetData, out imgData, out bitmap); picInsignia.Image = bitmap; } }
/// <summary> /// The worker thread that sends the request and handles timeouts /// </summary> /// <param name="threadContext">A <see cref="TaskInfo"/> object containing the request details</param> private void TextureRequestDoWork(Object threadContext) { TaskInfo task = (TaskInfo)threadContext; task.State = TextureRequestState.Progress; #if DEBUG_TIMING task.NetworkTime = DateTime.UtcNow; #endif // Find the first missing packet in the download ushort packet = 0; lock (task.Transfer) if (task.Transfer.PacketsSeen != null && task.Transfer.PacketsSeen.Count > 0) { packet = GetFirstMissingPacket(task.Transfer.PacketsSeen); } // Request the texture RequestImage(task.RequestID, task.Type, task.Transfer.Priority, task.Transfer.DiscardLevel, packet); // Set starting time task.Transfer.TimeSinceLastPacket = 0; // Don't release this worker slot until texture is downloaded or timeout occurs if (!resetEvents[task.RequestSlot].WaitOne()) { // Timed out Logger.Log("Worker " + task.RequestSlot + " timeout waiting for texture " + task.RequestID + " to download got " + task.Transfer.Transferred + " of " + task.Transfer.Size, Helpers.LogLevel.Warning); AssetTexture texture = new AssetTexture(task.RequestID, task.Transfer.AssetData); foreach (TextureDownloadCallback callback in task.Callbacks) { callback(TextureRequestState.Timeout, texture); } _Client.Assets.FireImageProgressEvent(task.RequestID, task.Transfer.Transferred, task.Transfer.Size); RemoveTransfer(task.RequestID); } // Free up this download slot lock (lockerObject) threadpoolSlots[task.RequestSlot] = -1; }
private void AssetImageFactory(ImageDownload image, AssetTexture asset) { string extension = "tga"; byte[] data = asset.AssetData; switch (asset.AssetType) { case AssetType.ImageJPEG: extension = "jpg"; break; case AssetType.Texture: if (asset.Decode()) data = asset.Image.ExportTGA(); else data = null; break; } if (data == null) return; Ox.IO.Save(string.Format("{0}.{1}", asset.AssetID.ToString(), extension), data); }
private void ProcessImageReceived(ImageDownload image, AssetTexture asset) { if (image.Success) AssetFactoryEnqueue(new QueueAsset(image, asset)); }
void Assets_OnImageReceived(ImageDownload image, AssetTexture asset) { lock (processQueue) processQueue.Enqueue(new QueueBase(new AssetManager.ImageReceivedCallback(ProcessImageReceived), image, asset)); }
private void imageReceivedCallback(ImageDownload image, AssetTexture asset) { if (OnImageReceived != null) { OnImageReceived(asset); } }
private void Assets_OnImageReceived(ImageDownload image, AssetTexture asset) { int requestNbr; bool found; lock (syncObject) found = currentRequests.TryGetValue(image.ID, out requestNbr); if (asset != null && found) { Logger.DebugLog(String.Format("Worker {0} Downloaded texture {1}", requestNbr, image.ID)); // Free up this slot in the ThreadPool lock (syncObject) currentRequests.Remove(image.ID); resetEvents[requestNbr].Set(); if (image.Success) { // Add to the completed texture dictionary lock (syncObject) completedDownloads[image.ID] = image; } else { Logger.Log(String.Format("Download of texture {0} failed. NotFound={1}", image.ID, image.NotFound), Helpers.LogLevel.Warning); } // Let any subscribers know about it if (OnDownloadFinished != null) OnDownloadFinished(image.ID, image.Success); } }
private void Assets_OnImageReceived(ImageDownload image, AssetTexture assetTexture) { lock (OutfitAssets) { if (OutfitAssets.Contains(image.ID)) { if (image.Success) { try { File.WriteAllBytes(image.ID.ToString() + ".jp2", image.AssetData); Console.WriteLine("Wrote JPEG2000 image " + image.ID.ToString() + ".jp2"); ManagedImage imgData; OpenJPEG.DecodeToImage(image.AssetData, out imgData); byte[] tgaFile = imgData.ExportTGA(); File.WriteAllBytes(image.ID.ToString() + ".tga", tgaFile); Console.WriteLine("Wrote TGA image " + image.ID.ToString() + ".tga"); } catch (Exception e) { Console.WriteLine(e.ToString()); } } else { Console.WriteLine("Failed to download image " + image.ID.ToString()); } OutfitAssets.Remove(image.ID); if (OutfitAssets.Count == 0) Client.Assets.OnImageReceived -= ImageReceivedHandler; } } }
private Asset CreateAssetWrapper(AssetType type) { Asset asset; switch (type) { case AssetType.Notecard: asset = new AssetNotecard(); break; case AssetType.LSLText: asset = new AssetScriptText(); break; case AssetType.LSLBytecode: asset = new AssetScriptBinary(); break; case AssetType.Texture: asset = new AssetTexture(); break; case AssetType.Object: asset = new AssetPrim(); break; case AssetType.Clothing: asset = new AssetClothing(); break; case AssetType.Bodypart: asset = new AssetBodypart(); break; case AssetType.Animation: asset = new AssetAnimation(); break; case AssetType.Sound: asset = new AssetSound(); break; default: Logger.Log("Unimplemented asset type: " + type, Helpers.LogLevel.Error, Client); return null; } return asset; }
void SendTexture(Agent agent, AssetTexture texture, int discardLevel, int packet, float priority) { ImageDownload download = new ImageDownload(texture, agent, discardLevel, priority, packet); Logger.DebugLog(String.Format( "[Periscope] Starting new texture transfer for {0}, DiscardLevel: {1}, Priority: {2}, Start: {3}, End: {4}, Total: {5}", texture.AssetID, discardLevel, priority, download.CurrentPacket, download.StopPacket, download.TexturePacketCount())); // Send initial data ImageDataPacket data = new ImageDataPacket(); data.ImageID.Codec = (byte)ImageCodec.J2C; data.ImageID.ID = download.Texture.AssetID; data.ImageID.Packets = (ushort)download.TexturePacketCount(); data.ImageID.Size = (uint)download.Texture.AssetData.Length; // The first bytes of the image are always sent in the ImageData packet data.ImageData = new ImageDataPacket.ImageDataBlock(); int imageDataSize = (download.Texture.AssetData.Length >= ImageDownload.FIRST_IMAGE_PACKET_SIZE) ? ImageDownload.FIRST_IMAGE_PACKET_SIZE : download.Texture.AssetData.Length; try { data.ImageData.Data = new byte[imageDataSize]; Buffer.BlockCopy(download.Texture.AssetData, 0, data.ImageData.Data, 0, imageDataSize); } catch (Exception ex) { Logger.Log(String.Format("{0}: imageDataSize={1}", ex.Message, imageDataSize), Helpers.LogLevel.Error); } server.UDP.SendPacket(agent.Avatar.ID, data, PacketCategory.Texture); // Check if ImagePacket packets need to be sent to complete this transfer if (download.CurrentPacket <= download.StopPacket) { // Insert this download into the dictionary lock (currentDownloads) currentDownloads[texture.AssetID] = download; // Send all of the remaining packets ThreadPool.QueueUserWorkItem( delegate(object obj) { while (download.CurrentPacket <= download.StopPacket) { if (download.Priority == 0.0f && download.DiscardLevel == -1) break; lock (download) { int imagePacketSize = (download.CurrentPacket == download.TexturePacketCount() - 1) ? download.LastPacketSize() : ImageDownload.IMAGE_PACKET_SIZE; ImagePacketPacket transfer = new ImagePacketPacket(); transfer.ImageID.ID = texture.AssetID; transfer.ImageID.Packet = (ushort)download.CurrentPacket; transfer.ImageData.Data = new byte[imagePacketSize]; try { Buffer.BlockCopy(download.Texture.AssetData, download.CurrentBytePosition(), transfer.ImageData.Data, 0, imagePacketSize); } catch (Exception ex) { Logger.Log(String.Format( "{0}: CurrentBytePosition()={1}, AssetData.Length={2} imagePacketSize={3}", ex.Message, download.CurrentBytePosition(), download.Texture.AssetData.Length, imagePacketSize), Helpers.LogLevel.Error); } server.UDP.SendPacket(agent.Avatar.ID, transfer, PacketCategory.Texture); ++download.CurrentPacket; } } Logger.DebugLog("Completed image transfer for " + texture.AssetID.ToString()); // Transfer is complete, remove the reference lock (currentDownloads) currentDownloads.Remove(texture.AssetID); } ); } }
/// <summary> /// Initiate an image download. This is an asynchronous function /// </summary> /// <param name="imageID">The image to download</param> /// <param name="type">Type of the image to download, either a baked /// avatar texture or a normal texture</param> /// <param name="priority">Priority level of the download. Default is /// <c>1,013,000.0f</c></param> /// <param name="discardLevel">Number of quality layers to discard. /// This controls the end marker of the data sent</param> /// <param name="packetNum">Packet number to start the download at. /// This controls the start marker of the data sent</param> /// <remarks>Sending a priority of 0 and a discardlevel of -1 aborts /// download</remarks> public void RequestImage(UUID imageID, ImageType type, float priority, int discardLevel, uint packetNum) { if (Cache.HasImage(imageID)) { ImageDownload transfer = Cache.GetCachedImage(imageID); transfer.ImageType = type; if (null != transfer) { if (null != OnImageReceived) { AssetTexture asset = new AssetTexture(transfer.ID, transfer.AssetData); try { OnImageReceived(transfer, asset); } catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } } return; } } // Priority == 0 && DiscardLevel == -1 means cancel the transfer if (priority.Equals(0) && discardLevel.Equals(-1)) { if (Transfers.ContainsKey(imageID)) Transfers.Remove(imageID); RequestImagePacket cancel = new RequestImagePacket(); cancel.AgentData.AgentID = Client.Self.AgentID; cancel.AgentData.SessionID = Client.Self.SessionID; cancel.RequestImage = new RequestImagePacket.RequestImageBlock[1]; cancel.RequestImage[0] = new RequestImagePacket.RequestImageBlock(); cancel.RequestImage[0].DiscardLevel = -1; cancel.RequestImage[0].DownloadPriority = 0; cancel.RequestImage[0].Packet = 0; cancel.RequestImage[0].Image = imageID; cancel.RequestImage[0].Type = 0; } else { Simulator currentSim = Client.Network.CurrentSim; if (!Transfers.ContainsKey(imageID)) { // New download ImageDownload transfer = new ImageDownload(); transfer.ID = imageID; transfer.Simulator = currentSim; transfer.ImageType = type; transfer.DiscardLevel = discardLevel; transfer.Priority = priority; // Add this transfer to the dictionary lock (Transfers) Transfers[transfer.ID] = transfer; Logger.DebugLog("Adding image " + imageID.ToString() + " to the download queue"); } else { // Already downloading, just updating the priority Transfer transfer = Transfers[imageID]; float percentComplete = ((float)transfer.Transferred / (float)transfer.Size) * 100f; if (Single.IsNaN(percentComplete)) percentComplete = 0f; Logger.DebugLog(String.Format("Updating priority on image transfer {0}, {1}% complete", imageID, Math.Round(percentComplete, 2))); } // Build and send the request packet RequestImagePacket request = new RequestImagePacket(); request.AgentData.AgentID = Client.Self.AgentID; request.AgentData.SessionID = Client.Self.SessionID; request.RequestImage = new RequestImagePacket.RequestImageBlock[1]; request.RequestImage[0] = new RequestImagePacket.RequestImageBlock(); request.RequestImage[0].DiscardLevel = (sbyte)discardLevel; request.RequestImage[0].DownloadPriority = priority; request.RequestImage[0].Packet = packetNum; request.RequestImage[0].Image = imageID; request.RequestImage[0].Type = (byte)type; Client.Network.SendPacket(request, currentSim); } }
/// <summary> /// Requests multiple Images /// </summary> /// <param name="Images">List of requested images</param> public void RequestImages(List<ImageRequest> Images) { for (int iri = 0; iri < Images.Count; iri++) { if (Transfers.ContainsKey(Images[iri].ImageID)) { Images.RemoveAt(iri); } if (Cache.HasImage(Images[iri].ImageID)) { ImageDownload transfer = Cache.GetCachedImage(Images[iri].ImageID); if (null != transfer) { if (null != OnImageReceived) { AssetTexture asset = new AssetTexture(transfer.ID, transfer.AssetData); try { OnImageReceived(transfer, asset); } catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } } Images.RemoveAt(iri); } } } if (Images.Count > 0) { // Build and send the request packet RequestImagePacket request = new RequestImagePacket(); request.AgentData.AgentID = Client.Self.AgentID; request.AgentData.SessionID = Client.Self.SessionID; request.RequestImage = new RequestImagePacket.RequestImageBlock[Images.Count]; for (int iru = 0; iru < Images.Count; ++iru) { ImageDownload transfer = new ImageDownload(); //transfer.AssetType = AssetType.Texture // Handled in ImageDataHandler. transfer.ID = Images[iru].ImageID; transfer.Simulator = Client.Network.CurrentSim; transfer.ImageType = Images[iru].Type; transfer.DiscardLevel = Images[iru].DiscardLevel; transfer.Priority = Images[iru].Priority; // Add this transfer to the dictionary lock (Transfers) Transfers[transfer.ID] = transfer; request.RequestImage[iru] = new RequestImagePacket.RequestImageBlock(); request.RequestImage[iru].DiscardLevel = (sbyte)Images[iru].DiscardLevel; request.RequestImage[iru].DownloadPriority = Images[iru].Priority; request.RequestImage[iru].Packet = 0; request.RequestImage[iru].Image = Images[iru].ImageID; request.RequestImage[iru].Type = (byte)Images[iru].Type; } Client.Network.SendPacket(request, Client.Network.CurrentSim); } else { Logger.Log("RequestImages() called for an image(s) we are already downloading or an empty list, ignoring", Helpers.LogLevel.Info, Client); } }
/// <summary> /// Handles the Image Data packet which includes the ID and Size of the image, /// along with the first block of data for the image. If the image is small enough /// there will be no additional packets /// </summary> private void ImageDataHandler(Packet packet, Simulator simulator) { ImageDataPacket data = (ImageDataPacket)packet; ImageDownload transfer = null; Logger.DebugLog(String.Format("ImageData: Size={0}, Packets={1}", data.ImageID.Size, data.ImageID.Packets)); lock (Transfers) { if (Transfers.ContainsKey(data.ImageID.ID)) { transfer = (ImageDownload)Transfers[data.ImageID.ID]; // Don't set header information if we have already // received it (due to re-request) if (transfer.Size == 0) { //Client.DebugLog("Received first " + data.ImageData.Data.Length + " bytes for image " + // data.ImageID.ID.ToString()); if (OnImageReceiveProgress != null) { try { OnImageReceiveProgress(data.ImageID.ID, 0, data.ImageData.Data.Length, transfer.Size); } catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } } transfer.Codec = (ImageCodec)data.ImageID.Codec; transfer.PacketCount = data.ImageID.Packets; transfer.Size = (int)data.ImageID.Size; transfer.AssetData = new byte[transfer.Size]; transfer.AssetType = AssetType.Texture; transfer.PacketsSeen = new SortedList<ushort, ushort>(); Buffer.BlockCopy(data.ImageData.Data, 0, transfer.AssetData, 0, data.ImageData.Data.Length); transfer.InitialDataSize = data.ImageData.Data.Length; transfer.Transferred += data.ImageData.Data.Length; // Check if we downloaded the full image if (transfer.Transferred >= transfer.Size) { Transfers.Remove(transfer.ID); transfer.Success = true; Cache.SaveImageToCache(transfer.ID, transfer.AssetData); } } } } if (transfer != null) { transfer.HeaderReceivedEvent.Set(); if (OnImageReceived != null && transfer.Transferred >= transfer.Size) { AssetTexture asset = new AssetTexture(transfer.ID, transfer.AssetData); try { OnImageReceived(transfer, asset); } catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } } } }
/// <summary> /// Handles the remaining Image data that did not fit in the initial ImageData packet /// </summary> private void ImagePacketHandler(Packet packet, Simulator simulator) { ImagePacketPacket image = (ImagePacketPacket)packet; ImageDownload transfer = null; lock (Transfers) { if (Transfers.ContainsKey(image.ImageID.ID)) { transfer = (ImageDownload)Transfers[image.ImageID.ID]; if (transfer.Size == 0) { // We haven't received the header yet, block until it's received or times out transfer.HeaderReceivedEvent.WaitOne(1000 * 5, false); if (transfer.Size == 0) { Logger.Log("Timed out while waiting for the image header to download for " + transfer.ID.ToString(), Helpers.LogLevel.Warning, Client); transfer.Success = false; Transfers.Remove(transfer.ID); goto Callback; } } // The header is downloaded, we can insert this data in to the proper position // Only insert if we haven't seen this packet before lock (transfer.PacketsSeen) { if (!transfer.PacketsSeen.ContainsKey(image.ImageID.Packet)) { transfer.PacketsSeen[image.ImageID.Packet] = image.ImageID.Packet; Buffer.BlockCopy(image.ImageData.Data, 0, transfer.AssetData, transfer.InitialDataSize + (1000 * (image.ImageID.Packet - 1)), image.ImageData.Data.Length); transfer.Transferred += image.ImageData.Data.Length; } } //Client.DebugLog("Received " + image.ImageData.Data.Length + "/" + transfer.Transferred + // "/" + transfer.Size + " bytes for image " + image.ImageID.ID.ToString()); transfer.TimeSinceLastPacket = 0; if (OnImageReceiveProgress != null) { try { OnImageReceiveProgress(image.ImageID.ID, image.ImageID.Packet, transfer.Transferred, transfer.Size); } catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } } // Check if we downloaded the full image if (transfer.Transferred >= transfer.Size) { Cache.SaveImageToCache(transfer.ID, transfer.AssetData); transfer.Success = true; Transfers.Remove(transfer.ID); } } } Callback: if (transfer != null && OnImageReceived != null && (transfer.Transferred >= transfer.Size || transfer.Size == 0)) { AssetTexture asset = new AssetTexture(transfer.ID, transfer.AssetData); try { OnImageReceived(transfer, asset); } catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } } }
// LibOMV callback for completed image texture. public void imageReceivedCallback(AssetTexture asset) { if (asset == null) { m_log.Debug("[TEXTURE]: GotLIBOMV callback but asset was null"); lock (ouststandingRequests) { } return; } m_log.Debug("[TEXTURE]: GotLIBOMV callback for asset" + asset.AssetID); lock (downloadQueue) { if (downloadQueue.ContainsKey(asset.AssetID)) downloadQueue.Remove(asset.AssetID); } bool result = false; bool bNonJp2000 = true; string strExtension = ".tga"; try { if (asset is AssetTexture) { bNonJp2000 = false; result = asset.Decode(); } else { //Paupaw:Get the AssetType switch (((OpenViewer.Primitives.ExtendedAssetTexture)asset).ExtAssetType) { case (int)AssetType.ImageJPEG: result = true; strExtension = ".jpg"; break; case (int)AssetType.ImageTGA: result = true; strExtension = ".tga"; break; case (int)AssetType.Texture: //JP2000 bNonJp2000 = false; result = asset.Decode(); break; } } } catch (Exception) { m_log.Debug("[TEXTURE]: Failed to decode asset " + asset.AssetID); } if (result) { // Write it to disk for picking up later in the pipeline. string texturefolderpath = imagefolder; string texturepath = System.IO.Path.Combine(texturefolderpath,asset.AssetID.ToString() + strExtension); byte[] imgdata = null; if (bNonJp2000) { imgdata = asset.AssetData; } else { imgdata = asset.Image.ExportTGA(); } FileStream fi = (File.Open(texturepath, FileMode.Create)); BinaryWriter bw = new BinaryWriter(fi); bw.Write(imgdata); bw.Flush(); bw.Close(); // Update nodes that the texture is downloaded. List<VObject> nodesToUpdate = new List<VObject>(); lock (ouststandingRequests) { if (ouststandingRequests.ContainsKey(asset.AssetID)) { nodesToUpdate = ouststandingRequests[asset.AssetID]; ouststandingRequests.Remove(asset.AssetID); } } lock (nodesToUpdate) { for (int i = 0; i < nodesToUpdate.Count; i++) { VObject vObj = nodesToUpdate[i]; if (vObj != null) { if (OnTextureLoaded != null) { OnTextureLoaded(asset.AssetID.ToString(), strExtension, vObj, asset.AssetID); } } } } } }
private void Assets_OnImageReceived(ImageDownload image, AssetTexture assetTexture) { lock (ImageDownloads) { if (ImageDownloads.ContainsKey(image.ID)) { ImageDownloads.Remove(image.ID); // NOTE: This image may occupy more than one TextureIndex! We must finish this loop for (int at = 0; at < AgentTextures.Length; at++) { if (AgentTextures[at] == image.ID) { TextureIndex index = (TextureIndex)at; BakeType type = Baker.BakeTypeFor(index); //BinaryWriter writer = new BinaryWriter(File.Create("wearable_" + index.ToString() + "_" + image.ID.ToString() + ".jp2")); //writer.Write(image.AssetData); //writer.Close(); bool baked = false; AgentAssets[at]=assetTexture; //Cache this asset for rebaking, todo this could be better rather than dropping in this list. if (PendingBakes.ContainsKey(type)) { if (image.Success) { Logger.DebugLog("Finished downloading texture for " + index.ToString(), Client); OpenJPEG.DecodeToImage(image.AssetData, out assetTexture.Image); baked = PendingBakes[type].AddTexture(index, assetTexture, false); } else { Logger.Log("Texture for " + index.ToString() + " failed to download, " + "bake will be incomplete", Helpers.LogLevel.Warning, Client); baked = PendingBakes[type].MissingTexture(index); } } if (baked) { UploadBake(PendingBakes[type]); PendingBakes.Remove(type); } if (ImageDownloads.Count == 0 && PendingUploads.Count == 0) { // This is a failsafe catch, as the upload completed callback should normally // be triggering the event Logger.DebugLog("No pending downloads or uploads detected in OnImageReceived", Client); CachedResponseEvent.Set(); } else { Logger.DebugLog("Pending uploads: " + PendingUploads.Count + ", pending downloads: " + ImageDownloads.Count, Client); } } } } else { Logger.Log("Received an image download callback for an image we did not request " + image.ID.ToString(), Helpers.LogLevel.Warning, Client); } } }
private void Assets_OnImageReceived(ImageDownload image, AssetTexture asset) { if (Textures.Contains(image.ID)) { lock (Textures) Textures.Remove(image.ID); if (image.Success) { try { File.WriteAllBytes(image.ID.ToString() + ".jp2", asset.AssetData); } catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client); } if (asset.Decode()) { try { File.WriteAllBytes(image.ID.ToString() + ".tga", asset.Image.ExportTGA()); } catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client); } } else { Logger.Log("Failed to decode image " + image.ID.ToString(), Helpers.LogLevel.Error, Client); } Logger.Log("Finished downloading image " + image.ID.ToString(), Helpers.LogLevel.Info, Client); } else { Logger.Log("Failed to download image " + image.ID.ToString(), Helpers.LogLevel.Warning, Client); } } }
// LibOMV callback for completed image texture. public void imageReceivedCallback(AssetTexture asset) { if (asset == null) { m_log.Debug("[TEXTURE]: GotLIBOMV callback but asset was null"); return; } m_log.Debug("[TEXTURE]: GotLIBOMV callback for asset" + asset.AssetID); lock (downloadQueue) { if (downloadQueue.ContainsKey(asset.AssetID)) downloadQueue.Remove(asset.AssetID); } bool result = false; bool bNonJp2000 = true; string extension = string.Empty; try { AssetType type = asset.AssetType; if (asset is OpenViewer.Primitives.ExtendedAssetTexture) { type = (AssetType)((OpenViewer.Primitives.ExtendedAssetTexture)asset).ExtAssetType; //Paupaw:Get the AssetType switch (type) { case AssetType.ImageJPEG: result = true; extension = ".jpg"; break; case AssetType.ImageTGA: result = true; extension = ".tga"; break; case AssetType.Texture: //JP2000 bNonJp2000 = false; result = asset.Decode(); extension = ".tga"; break; } } else if (asset is AssetTexture) { bNonJp2000 = false; result = asset.Decode(); extension = ".tga"; } else { result = true; extension = ".jpg"; } } catch (Exception e) { //m_log.Debug("[TEXTURE]: Failed to decode asset " + asset.AssetID); if (!bNonJp2000) { bNonJp2000 = true; result = true; extension = ".jpg"; } } if (result) { byte[] imgdata = null; if (bNonJp2000) imgdata = asset.AssetData; else imgdata = asset.Image.ExportTGA(); string texturefolderpath = imagefolder; string texturepath = System.IO.Path.Combine(texturefolderpath, asset.AssetID.ToString() + extension); FileStream fs = (File.Open(texturepath, FileMode.Create)); BinaryWriter bw = new BinaryWriter(fs); bw.Write(imgdata); bw.Flush(); bw.Close(); // Immediately load it to memory if (File.Exists(System.IO.Path.Combine(texturefolderpath, asset.AssetID.ToString() + extension))) { Texture texTnorm = Reference.VideoDriver.GetTexture(System.IO.Path.Combine(texturefolderpath, asset.AssetID.ToString() + extension)); TextureExtended tex = new TextureExtended(texTnorm.Raw, extension); if (tex != null) { lock (memoryTextures) { if (!memoryTextures.ContainsKey(asset.AssetID)) { memoryTextures.Add(asset.AssetID, tex); } } } } // Update nodes that the texture is downloaded. List<VObject> nodesToUpdate = null; lock (outstandingRequests) { if (outstandingRequests.ContainsKey(asset.AssetID)) { nodesToUpdate = outstandingRequests[asset.AssetID]; outstandingRequests.Remove(asset.AssetID); } } if (nodesToUpdate == null) return; lock (nodesToUpdate) { for (int i = 0; i < nodesToUpdate.Count; i++) { VObject vObj = nodesToUpdate[i]; if (vObj == null || OnTextureLoaded == null) continue; OnTextureLoaded(asset.AssetID.ToString(), extension, vObj, asset.AssetID); Reference.Viewer.Adapter.CallReceiveImage(asset.AssetID.ToString()); } } } }
private void Assets_OnImageReceived(ImageDownload image, AssetTexture asset) { // Free up this slot in the ThreadPool lock (CurrentRequests) { int requestNbr; if (asset != null && CurrentRequests.TryGetValue(image.ID, out requestNbr)) { Logger.DebugLog(String.Format("Worker {0} Downloaded texture {1}", requestNbr, image.ID)); resetEvents[requestNbr].Set(); CurrentRequests.Remove(image.ID); } } if (image.Success) { lock (RenderReady) { if (!RenderReady.ContainsKey(image.ID)) { // Add to rendering dictionary RenderReady.Add(image.ID, image); } } } else { Console.WriteLine(String.Format("Download of texture {0} failed. NotFound={1}", image.ID, image.NotFound)); } // Let any subscribers know about it if (OnDownloadFinished != null) { OnDownloadFinished(image.ID, image.Success); } }