29 using System.Collections;
30 using System.Collections.Specialized;
32 using System.Drawing.Imaging;
33 using System.Reflection;
39 using OpenMetaverse.StructuredData;
40 using OpenMetaverse.Imaging;
41 using OpenSim.Framework;
42 using OpenSim.Framework.Servers;
43 using OpenSim.Framework.Servers.HttpServer;
44 using OpenSim.Region.Framework.Interfaces;
45 using OpenSim.Services.Interfaces;
48 namespace OpenSim.Capabilities.Handlers
52 private static readonly ILog m_log =
53 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
57 public const string DefaultFormat =
"x-j2c";
61 m_assetService = assService;
64 public Hashtable
Handle(Hashtable request)
66 Hashtable ret =
new Hashtable();
67 ret[
"int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
68 ret[
"content_type"] =
"text/plain";
69 ret[
"keepalive"] =
false;
70 ret[
"reusecontext"] =
false;
72 string textureStr = (
string)request[
"texture_id"];
73 string format = (string)request[
"format"];
77 if (m_assetService == null)
79 m_log.Error(
"[GETTEXTURE]: Cannot fetch texture " + textureStr +
" without an asset service");
83 if (!
String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID))
88 if (!
string.IsNullOrEmpty(format))
90 formats =
new string[1] { format.ToLower() };
94 formats =
new string[1] { DefaultFormat };
95 if (((Hashtable)request[
"headers"])[
"Accept"] != null)
96 formats = WebUtil.GetPreferredImageTypes((string)((Hashtable)request[
"headers"])[
"Accept"]);
97 if (formats.Length == 0)
98 formats =
new string[1] { DefaultFormat };
102 bool foundtexture =
false;
103 foreach (
string f
in formats)
105 foundtexture = FetchTexture(request, ret, textureID, f);
111 ret[
"int_response_code"] = 404;
112 ret[
"error_status_text"] =
"not found";
113 ret[
"str_response_string"] =
"not found";
114 ret[
"content_type"] =
"text/plain";
115 ret[
"keepalive"] =
false;
116 ret[
"reusecontext"] =
false;
117 ret[
"int_bytes"] = 0;
122 m_log.Warn(
"[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + (string)request[
"uri"]);
139 private bool FetchTexture(Hashtable request, Hashtable response,
UUID textureID,
string format)
144 string fullID = textureID.ToString();
145 if (format != DefaultFormat)
146 fullID = fullID +
"-" +
format;
149 texture = m_assetService.GetCached(fullID);
156 texture = m_assetService.Get(textureID.ToString());
160 if (texture.
Type != (sbyte)AssetType.Texture)
163 if (format == DefaultFormat)
165 WriteTextureData(request, response, texture, format);
171 newTexture.Data = ConvertTextureData(texture, format);
172 if (newTexture.
Data.Length == 0)
175 newTexture.Flags = AssetFlags.Collectable;
176 newTexture.Temporary =
true;
177 newTexture.Local =
true;
178 m_assetService.Store(newTexture);
179 WriteTextureData(request, response, newTexture, format);
187 WriteTextureData(request, response, texture, format);
200 private void WriteTextureData(Hashtable request, Hashtable response,
AssetBase texture,
string format)
202 Hashtable headers =
new Hashtable();
203 response[
"headers"] = headers;
205 string range = String.Empty;
207 if (((Hashtable)request[
"headers"])[
"range"] != null)
208 range = (string)((Hashtable)request[
"headers"])[
"range"];
210 else if (((Hashtable)request[
"headers"])[
"Range"] != null)
211 range = (
string)((Hashtable)request[
"headers"])[
"Range"];
213 if (!
String.IsNullOrEmpty(range))
217 if (TryParseRange(range, out start, out end))
221 if (start >= texture.
Data.Length)
240 response[
"int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
249 end = Utils.Clamp(end, 0, texture.Data.Length - 1);
250 start = Utils.Clamp(start, 0, end);
251 int len = end - start + 1;
255 response[
"content-type"] = texture.Metadata.ContentType;
257 if (start == 0 && len == texture.
Data.Length)
259 response[
"int_response_code"] = (int)System.Net.HttpStatusCode.OK;
260 response[
"bin_response_data"] = texture.
Data;
261 response[
"int_bytes"] = texture.
Data.Length;
265 response[
"int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
266 headers[
"Content-Range"] =
String.Format(
"bytes {0}-{1}/{2}", start, end, texture.
Data.Length);
268 byte[] d =
new byte[len];
269 Array.Copy(texture.Data, start, d, 0, len);
270 response[
"bin_response_data"] = d;
271 response[
"int_bytes"] = len;
278 m_log.Warn(
"[GETTEXTURE]: Malformed Range header: " + range);
279 response[
"int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
285 response[
"int_response_code"] = (int)System.Net.HttpStatusCode.OK;
286 if (format == DefaultFormat)
287 response[
"content_type"] = texture.Metadata.ContentType;
289 response[
"content_type"] =
"image/" +
format;
291 response[
"bin_response_data"] = texture.Data;
292 response[
"int_bytes"] = texture.Data.Length;
320 private bool TryParseRange(
string header, out
int start, out
int end)
324 if (header.StartsWith(
"bytes="))
326 string[] rangeValues = header.Substring(6).Split(
'-');
328 if (rangeValues.Length == 2)
330 if (!Int32.TryParse(rangeValues[0], out start))
333 string rawEnd = rangeValues[1];
340 else if (Int32.TryParse(rawEnd, out end))
351 private byte[] ConvertTextureData(
AssetBase texture,
string format)
353 m_log.DebugFormat(
"[GETTEXTURE]: Converting texture {0} to {1}", texture.ID,
format);
354 byte[] data =
new byte[0];
356 MemoryStream imgstream =
new MemoryStream();
357 Bitmap mTexture =
new Bitmap(1, 1);
358 ManagedImage managedImage;
359 Image image = (Image)mTexture;
365 imgstream =
new MemoryStream();
368 if (OpenJPEG.DecodeToImage(texture.
Data, out managedImage, out image))
371 mTexture =
new Bitmap(image);
373 EncoderParameters myEncoderParameters =
new EncoderParameters();
374 myEncoderParameters.Param[0] =
new EncoderParameter(Encoder.Quality, 95L);
377 ImageCodecInfo codec = GetEncoderInfo(
"image/" + format);
380 mTexture.Save(imgstream, codec, myEncoderParameters);
382 data = imgstream.ToArray();
385 m_log.WarnFormat(
"[GETTEXTURE]: No such codec {0}",
format);
391 m_log.WarnFormat(
"[GETTEXTURE]: Unable to convert texture {0} to {1}: {2}", texture.ID,
format, e.Message);
397 if (mTexture != null)
403 if (imgstream != null)
414 private static ImageCodecInfo GetEncoderInfo(
String mimeType)
416 ImageCodecInfo[] encoders;
417 encoders = ImageCodecInfo.GetImageEncoders();
418 for (
int j = 0; j < encoders.Length; ++j)
420 if (encoders[j].MimeType == mimeType)
OpenSim.Framework.Capabilities.Caps Caps
GetTextureHandler(IAssetService assService)
Hashtable Handle(Hashtable request)
OpenSim.Framework.Capabilities.Caps Caps
sbyte Type
(sbyte) AssetType enum
Asset class. All Assets are reference by this class or a class derived from this class ...
string ID
Asset MetaData ID (transferring from UUID to string ID)