2 // Radegast Metaverse Client
3 // Copyright (c) 2009-2014, Radegast Development Team
4 // All rights reserved.
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
9 // * Redistributions of source code must retain the above copyright notice,
10 // this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 // * Neither the name of the application "Radegast", nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 using System.Collections.Generic;
33 using System.ComponentModel;
35 using System.Drawing.Imaging;
39 using System.Windows.Forms;
42 using OpenMetaverse.Assets;
43 using OpenMetaverse.Imaging;
47 public partial class ImageUploadConsole : RadegastTabControl
49 public string FileName, TextureName, TextureDescription;
50 public byte[] UploadData;
51 public UUID InventoryID, AssetID, TransactionID;
53 int OriginalCapsTimeout;
55 public ImageUploadConsole()
57 InitializeComponent();
60 public ImageUploadConsole(RadegastInstance instance)
63 InitializeComponent();
65 Disposed += new EventHandler(ImageUploadConsole_Disposed);
66 instance.Netcom.ClientConnected += new EventHandler<EventArgs>(Netcom_ClientConnected);
67 instance.Netcom.ClientDisconnected += new EventHandler<DisconnectedEventArgs>(Netcom_ClientDisconnected);
68 client.Assets.AssetUploaded += new EventHandler<AssetUploadEventArgs>(Assets_AssetUploaded);
70 OriginalCapsTimeout = client.Settings.CAPS_TIMEOUT;
73 void ImageUploadConsole_Disposed(object sender, EventArgs e)
75 client.Assets.AssetUploaded -= new EventHandler<AssetUploadEventArgs>(Assets_AssetUploaded);
78 void Assets_AssetUploaded(object sender, AssetUploadEventArgs e)
80 if (e.Upload.ID == TransactionID)
82 if (!e.Upload.Success)
84 TempUploadHandler(false, new InventoryTexture(UUID.Zero));
88 client.Inventory.RequestCreateItem(client.Inventory.FindFolderForType(AssetType.Texture),
89 TextureName, TextureDescription, AssetType.Texture, TransactionID,
90 InventoryType.Texture, PermissionMask.All, TempUploadHandler);
95 void Netcom_ClientDisconnected(object sender, DisconnectedEventArgs e)
99 if (!instance.MonoRuntime || IsHandleCreated)
101 BeginInvoke(new MethodInvoker(() => Netcom_ClientDisconnected(sender, e)));
109 void Netcom_ClientConnected(object sender, EventArgs e)
113 if (!instance.MonoRuntime || IsHandleCreated)
115 BeginInvoke(new MethodInvoker(() => Netcom_ClientConnected(sender, e)));
123 private bool IsPowerOfTwo(uint n)
125 return (n & (n - 1)) == 0 && n != 0;
128 private int ClosestPowerOwTwo(int n)
137 return res > 1 ? res / 2 : 1;
140 public void LoadImage(string fname)
144 if (String.IsNullOrEmpty(FileName))
147 txtStatus.AppendText("Loading...\n");
149 string extension = System.IO.Path.GetExtension(FileName).ToLower();
150 Bitmap bitmap = null;
154 if (extension == ".jp2" || extension == ".j2c")
157 ManagedImage managedImage;
159 // Upload JPEG2000 images untouched
160 UploadData = System.IO.File.ReadAllBytes(FileName);
162 OpenJPEG.DecodeToImage(UploadData, out managedImage, out image);
163 bitmap = (Bitmap)image;
165 txtStatus.AppendText("Loaded raw JPEG2000 data " + FileName + "\n");
169 if (extension == ".tga")
171 bitmap = LoadTGAClass.LoadTGA(FileName);
175 bitmap = (Bitmap)System.Drawing.Image.FromFile(FileName);
179 txtStatus.AppendText("Loaded image " + FileName + "\n");
181 int width = bitmap.Width;
182 int height = bitmap.Height;
184 // Handle resizing to prevent excessively large images and irregular dimensions
185 if (!IsPowerOfTwo((uint)width) || !IsPowerOfTwo((uint)height) || width > 1024 || height > 1024)
187 txtStatus.AppendText("Image has irregular dimensions " + width + "x" + height + "\n");
189 width = ClosestPowerOwTwo(width);
190 height = ClosestPowerOwTwo(height);
192 width = width > 1024 ? 1024 : width;
193 height = height > 1024 ? 1024 : height;
195 txtStatus.AppendText("Resizing to " + width + "x" + height + "\n");
197 Bitmap resized = new Bitmap(width, height, bitmap.PixelFormat);
198 Graphics graphics = Graphics.FromImage(resized);
200 graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
201 graphics.InterpolationMode =
202 System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
203 graphics.DrawImage(bitmap, 0, 0, width, height);
209 txtStatus.AppendText("Encoding image...\n");
211 UploadData = OpenJPEG.EncodeFromImage(bitmap, chkLossless.Checked);
213 txtStatus.AppendText("Finished encoding.\n");
216 txtAssetID.Text = UUID.Zero.ToString();
218 pbPreview.Image = bitmap;
219 lblSize.Text = string.Format("{0}x{1} {2} KB", bitmap.Width, bitmap.Height, Math.Round((double)UploadData.Length / 1024.0d, 2));
224 btnSave.Enabled = false;
225 btnUpload.Enabled = false;
226 txtStatus.AppendText(string.Format("Failed to load the image:\n{0}\n", ex.Message));
233 btnLoad.Enabled = true;
237 btnSave.Enabled = true;
241 btnSave.Enabled = false;
244 if (ImageLoaded && client.Network.Connected)
246 btnUpload.Enabled = true;
250 btnUpload.Enabled = false;
255 private void btnLoad_Click(object sender, EventArgs e)
257 OpenFileDialog dialog = new OpenFileDialog();
259 "Image Files (*.jp2,*.j2c,*.jpg,*.jpeg,*.gif,*.png,*.bmp,*.tga,*.tif,*.tiff,*.ico,*.wmf,*.emf)|" +
260 "*.jp2;*.j2c;*.jpg;*.jpeg;*.gif;*.png;*.bmp;*.tga;*.tif;*.tiff;*.ico;*.wmf;*.emf|" +
261 "All files (*.*)|*.*";
263 if (dialog.ShowDialog() == DialogResult.OK)
265 LoadImage(dialog.FileName);
269 private void btnSave_Click(object sender, EventArgs e)
272 SaveFileDialog dlg = new SaveFileDialog();
273 dlg.AddExtension = true;
274 dlg.RestoreDirectory = true;
275 dlg.Title = "Save image as...";
276 dlg.Filter = "PNG (*.png)|*.png|Targa (*.tga)|*.tga|Jpeg2000 (*.j2c)|*.j2c|Jpeg (*.jpg)|*.jpg|Bitmap (*.bmp)|*.bmp";
280 if (dlg.ShowDialog() == DialogResult.OK)
282 int type = dlg.FilterIndex;
285 File.WriteAllBytes(dlg.FileName, UploadData);
289 ManagedImage imgManaged;
290 OpenJPEG.DecodeToImage(UploadData, out imgManaged);
291 File.WriteAllBytes(dlg.FileName, imgManaged.ExportTGA());
295 pbPreview.Image.Save(dlg.FileName, ImageFormat.Png);
299 pbPreview.Image.Save(dlg.FileName, ImageFormat.Jpeg);
303 pbPreview.Image.Save(dlg.FileName, ImageFormat.Bmp);
310 private void TempUploadHandler(bool success, InventoryItem item)
316 BeginInvoke(new MethodInvoker(() => TempUploadHandler(success, item)));
321 InventoryID = item.UUID;
324 txtAssetID.Text = AssetID.ToString();
328 txtStatus.AppendText("Upload failed.\n");
332 txtStatus.AppendText("Upload success.\n");
333 txtStatus.AppendText("New image ID: " + AssetID.ToString() + "\n");
336 private void UploadHandler(bool success, string status, UUID itemID, UUID assetID)
342 BeginInvoke(new MethodInvoker(() => UploadHandler(success, status, itemID, assetID)));
347 client.Settings.CAPS_TIMEOUT = OriginalCapsTimeout;
350 InventoryID = itemID;
353 txtAssetID.Text = AssetID.ToString();
357 txtStatus.AppendText("Upload failed: " + status + "\n");
361 txtStatus.AppendText("Upload success.\n");
362 txtStatus.AppendText("New image ID: " + AssetID.ToString() + "\n");
365 private void btnUpload_Click(object sender, EventArgs e)
367 bool tmp = chkTemp.Checked;
368 txtStatus.AppendText("Uploading...");
369 btnLoad.Enabled = false;
370 btnUpload.Enabled = false;
371 AssetID = InventoryID = UUID.Zero;
373 TextureName = Path.GetFileNameWithoutExtension(FileName);
374 if (tmp) TextureName += " (temp)";
375 TextureDescription = string.Format("Uploaded with Radegast on {0}", DateTime.Now.ToLongDateString());
377 Permissions perms = new Permissions();
378 perms.EveryoneMask = PermissionMask.All;
379 perms.NextOwnerMask = PermissionMask.All;
383 client.Settings.CAPS_TIMEOUT = 180 * 1000;
384 client.Inventory.RequestCreateItemFromAsset(UploadData, TextureName, TextureDescription, AssetType.Texture, InventoryType.Texture,
385 client.Inventory.FindFolderForType(AssetType.Texture), perms, UploadHandler);
389 TransactionID = UUID.Random();
390 client.Assets.RequestUpload(out AssetID, AssetType.Texture, UploadData, true, TransactionID);