From c062138dad42ef7e52bbcb27c346ddecab94c5af Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 30 Apr 2011 12:23:40 -0700 Subject: Moved several cap-based-service-providing modules from where they were into a newly created CoreModules/Caps. Not all. --- .../CoreModules/Avatar/Assets/GetTextureModule.cs | 402 --------------------- 1 file changed, 402 deletions(-) delete mode 100644 OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs (limited to 'OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs') diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs b/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs deleted file mode 100644 index df4d561..0000000 --- a/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Drawing; -using System.Drawing.Imaging; -using System.Reflection; -using System.IO; -using System.Web; -using log4net; -using Nini.Config; -using OpenMetaverse; -using OpenMetaverse.StructuredData; -using OpenMetaverse.Imaging; -using OpenSim.Framework; -using OpenSim.Framework.Servers; -using OpenSim.Framework.Servers.HttpServer; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Services.Interfaces; -using Caps = OpenSim.Framework.Capabilities.Caps; - -namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps -{ - #region Stream Handler - - public delegate byte[] StreamHandlerCallback(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse); - - public class StreamHandler : BaseStreamHandler - { - StreamHandlerCallback m_callback; - - public StreamHandler(string httpMethod, string path, StreamHandlerCallback callback) - : base(httpMethod, path) - { - m_callback = callback; - } - - public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - return m_callback(path, request, httpRequest, httpResponse); - } - } - - #endregion Stream Handler - - public class GetTextureModule : IRegionModule - { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private Scene m_scene; - private IAssetService m_assetService; - - public const string DefaultFormat = "x-j2c"; - - // TODO: Change this to a config option - const string REDIRECT_URL = null; - - - #region IRegionModule Members - - public void Initialise(Scene pScene, IConfigSource pSource) - { - m_scene = pScene; - } - - public void PostInitialise() - { - m_assetService = m_scene.RequestModuleInterface(); - m_scene.EventManager.OnRegisterCaps += RegisterCaps; - } - - public void Close() { } - - public string Name { get { return "GetTextureModule"; } } - public bool IsSharedModule { get { return false; } } - - public void RegisterCaps(UUID agentID, Caps caps) - { - UUID capID = UUID.Random(); - -// m_log.InfoFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); - caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); - } - - #endregion - - private byte[] ProcessGetTexture(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - //m_log.DebugFormat("[GETTEXTURE]: called in {0}", m_scene.RegionInfo.RegionName); - - // Try to parse the texture ID from the request URL - NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); - string textureStr = query.GetOne("texture_id"); - string format = query.GetOne("format"); - - if (m_assetService == null) - { - m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return null; - } - - UUID textureID; - if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID)) - { - string[] formats; - if (format != null && format != string.Empty) - { - formats = new string[1] { format.ToLower() }; - } - else - { - formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept")); - if (formats.Length == 0) - formats = new string[1] { DefaultFormat }; // default - - } - // OK, we have an array with preferred formats, possibly with only one entry - - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - foreach (string f in formats) - { - if (FetchTexture(httpRequest, httpResponse, textureID, f)) - break; - } - - } - else - { - m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url); - } - - httpResponse.Send(); - return null; - } - - /// - /// - /// - /// - /// - /// - /// - /// False for "caller try another codec"; true otherwise - private bool FetchTexture(OSHttpRequest httpRequest, OSHttpResponse httpResponse, UUID textureID, string format) - { -// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format); - AssetBase texture; - - string fullID = textureID.ToString(); - if (format != DefaultFormat) - fullID = fullID + "-" + format; - - if (!String.IsNullOrEmpty(REDIRECT_URL)) - { - // Only try to fetch locally cached textures. Misses are redirected - texture = m_assetService.GetCached(fullID); - - if (texture != null) - { - if (texture.Type != (sbyte)AssetType.Texture) - { - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return true; - } - WriteTextureData(httpRequest, httpResponse, texture, format); - } - else - { - string textureUrl = REDIRECT_URL + textureID.ToString(); - m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl); - httpResponse.RedirectLocation = textureUrl; - return true; - } - } - else // no redirect - { - // try the cache - texture = m_assetService.GetCached(fullID); - - if (texture == null) - { - //m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache"); - - // Fetch locally or remotely. Misses return a 404 - texture = m_assetService.Get(textureID.ToString()); - - if (texture != null) - { - if (texture.Type != (sbyte)AssetType.Texture) - { - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return true; - } - if (format == DefaultFormat) - { - WriteTextureData(httpRequest, httpResponse, texture, format); - return true; - } - else - { - AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID); - newTexture.Data = ConvertTextureData(texture, format); - if (newTexture.Data.Length == 0) - return false; // !!! Caller try another codec, please! - - newTexture.Flags = AssetFlags.Collectable; - newTexture.Temporary = true; - m_assetService.Store(newTexture); - WriteTextureData(httpRequest, httpResponse, newTexture, format); - return true; - } - } - } - else // it was on the cache - { - //m_log.DebugFormat("[GETTEXTURE]: texture was in the cache"); - WriteTextureData(httpRequest, httpResponse, texture, format); - return true; - } - } - - // not found -// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return true; - } - - private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format) - { - string range = request.Headers.GetOne("Range"); - //m_log.DebugFormat("[GETTEXTURE]: Range {0}", range); - if (!String.IsNullOrEmpty(range)) // JP2's only - { - // Range request - int start, end; - if (TryParseRange(range, out start, out end)) - { - // Before clamping start make sure we can satisfy it in order to avoid - // sending back the last byte instead of an error status - if (start >= texture.Data.Length) - { - response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; - return; - } - - end = Utils.Clamp(end, 0, texture.Data.Length - 1); - start = Utils.Clamp(start, 0, end); - int len = end - start + 1; - - //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); - - if (len < texture.Data.Length) - response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; - - response.ContentLength = len; - response.ContentType = texture.Metadata.ContentType; - response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length)); - - response.Body.Write(texture.Data, start, len); - } - else - { - m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range); - response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest; - } - } - else // JP2's or other formats - { - // Full content request - response.StatusCode = (int)System.Net.HttpStatusCode.OK; - response.ContentLength = texture.Data.Length; - if (format == DefaultFormat) - response.ContentType = texture.Metadata.ContentType; - else - response.ContentType = "image/" + format; - response.Body.Write(texture.Data, 0, texture.Data.Length); - } - } - - private bool TryParseRange(string header, out int start, out int end) - { - if (header.StartsWith("bytes=")) - { - string[] rangeValues = header.Substring(6).Split('-'); - if (rangeValues.Length == 2) - { - if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end)) - return true; - } - } - - start = end = 0; - return false; - } - - - private byte[] ConvertTextureData(AssetBase texture, string format) - { - m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format); - byte[] data = new byte[0]; - - MemoryStream imgstream = new MemoryStream(); - Bitmap mTexture = new Bitmap(1, 1); - ManagedImage managedImage; - Image image = (Image)mTexture; - - try - { - // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data - - imgstream = new MemoryStream(); - - // Decode image to System.Drawing.Image - if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image)) - { - // Save to bitmap - mTexture = new Bitmap(image); - - EncoderParameters myEncoderParameters = new EncoderParameters(); - myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L); - - // Save bitmap to stream - ImageCodecInfo codec = GetEncoderInfo("image/" + format); - if (codec != null) - { - mTexture.Save(imgstream, codec, myEncoderParameters); - // Write the stream to a byte array for output - data = imgstream.ToArray(); - } - else - m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format); - - } - } - catch (Exception e) - { - m_log.WarnFormat("[GETTEXTURE]: Unable to convert texture {0} to {1}: {2}", texture.ID, format, e.Message); - } - finally - { - // Reclaim memory, these are unmanaged resources - // If we encountered an exception, one or more of these will be null - if (mTexture != null) - mTexture.Dispose(); - - if (image != null) - image.Dispose(); - - if (imgstream != null) - { - imgstream.Close(); - imgstream.Dispose(); - } - } - - return data; - } - - // From msdn - private static ImageCodecInfo GetEncoderInfo(String mimeType) - { - ImageCodecInfo[] encoders; - encoders = ImageCodecInfo.GetImageEncoders(); - for (int j = 0; j < encoders.Length; ++j) - { - if (encoders[j].MimeType == mimeType) - return encoders[j]; - } - return null; - } - - - } -} -- cgit v1.1