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);
            }
        }
예제 #2
0
파일: Asset.cs 프로젝트: yooyke/work
        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 { }
            }
        }
예제 #3
0
        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]";
            }
        }
예제 #5
0
 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);
     }
 }
예제 #6
0
        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;
            }
        }
예제 #7
0
        /// <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;
        }
예제 #8
0
        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);
        }
예제 #9
0
 private void ProcessImageReceived(ImageDownload image, AssetTexture asset)
 {
     if (image.Success)
         AssetFactoryEnqueue(new QueueAsset(image, asset));
 }
예제 #10
0
 void Assets_OnImageReceived(ImageDownload image, AssetTexture asset)
 {
     lock (processQueue) processQueue.Enqueue(new QueueBase(new AssetManager.ImageReceivedCallback(ProcessImageReceived), image, asset));
 }
예제 #11
0
 private void imageReceivedCallback(ImageDownload image, AssetTexture asset)
 {
     if (OnImageReceived != null)
     {
         OnImageReceived(asset);
     }
 }
예제 #12
0
        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);
            }
        }
예제 #13
0
        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;
                }
            }
        }
예제 #14
0
        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);
                    }
                );
            }
        }
예제 #16
0
        /// <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);
            }
        }
예제 #17
0
        /// <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);
            }
        }
예제 #18
0
        /// <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); }
                }
            }
        }
예제 #19
0
        /// <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); }
            }
        }
예제 #20
0
        // 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);
                            }
                            
                        }
                        
                    }
                }
            }
        }
예제 #21
0
        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);
                }
            }
        }
예제 #22
0
        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);
                }
            }
        }
예제 #23
0
        // 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());
                    }
                }
            }
        }
예제 #24
0
        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);
            }
        }