Skip to content

Commit

Permalink
Merge pull request #53 from bkeiren/fix_memory_usage
Browse files Browse the repository at this point in the history
Fix memory usage
  • Loading branch information
bkeiren authored Dec 13, 2017
2 parents 5813862 + cc9e6a0 commit 8876c9e
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 102 deletions.
4 changes: 2 additions & 2 deletions EasyImgur/APIResponses/AlbumResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ public class Data : BaseResponse.BaseData
public string Cover { get; set; }

[JsonProperty("cover_width")]
public int CoverWidth { get; set; }
public int? CoverWidth { get; set; }

[JsonProperty("cover_height")]
public int CoverHeight { get; set; }
public int? CoverHeight { get; set; }

[JsonProperty("account_url")]
public string AccountUrl { get; set; }
Expand Down
24 changes: 13 additions & 11 deletions EasyImgur/FileHelper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Drawing.Imaging;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;

namespace EasyImgur
Expand All @@ -17,12 +19,12 @@ static class FileHelper
/// </summary>
/// <param name="location">Path of the file to write</param>
/// <param name="contents">Text to write to file</param>
public static void GZipWriteFile(string location, string contents)
public static void GZipWriteFile( string _Location, string _Contents )
{
byte[] sourceBytes = Encoding.UTF8.GetBytes(contents); // UTF-8 without BOM
byte[] sourceBytes = Encoding.UTF8.GetBytes(_Contents); // UTF-8 without BOM

using (var inStream = new MemoryStream(sourceBytes))
using (var fs = new FileStream(location, FileMode.Create, FileAccess.Write)) // Open file for writing, overwrite existing
using (var fs = new FileStream(_Location, FileMode.Create, FileAccess.Write)) // Open file for writing, overwrite existing
using (var outStream = new GZipStream(fs, CompressionMode.Compress))
{
inStream.CopyTo(outStream);
Expand All @@ -34,16 +36,16 @@ public static void GZipWriteFile(string location, string contents)
/// </summary>
/// <param name="location">Path of the file to read.</param>
/// <returns>Decompressed contents of the file.</returns>
public static string GZipReadFile(string location)
public static string GZipReadFile( string _Location )
{
// 4096 is the default buffer size. Don't know if PeekBytes conflicts with
// SequentialScan but there doesn't appear to be any difference.
using (var fs = new FileStream(location, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan))
using (var fs = new FileStream(_Location, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan))
{
Stream inStream;

// Check if file starts with the gzip magic number
if (BitConverter.ToUInt16(fs.PeekBytes(2), 0) != GZipMagicNumber) // Could this be shorter with `?:`? Yes! Would it be legible? No!
if (BitConverter.ToUInt16(PeekBytes(fs, 2), 0) != GZipMagicNumber) // Could this be shorter with `?:`? Yes! Would it be legible? No!
{
// Not gzip-compressed, probably old history file version in plain text
// or machine is big-endian. We'll worry about the latter when someone
Expand Down Expand Up @@ -71,14 +73,14 @@ public static string GZipReadFile(string location)
/// <param name="stream">Stream to peek</param>
/// <param name="count">Amount of bytes to peek</param>
/// <returns>Peeked bytes</returns>
public static byte[] PeekBytes(this Stream stream, int count)
public static byte[] PeekBytes( Stream _Stream, int _Count )
{
var buffer = new byte[count];
if (!stream.CanSeek)
var buffer = new byte[_Count];
if (!_Stream.CanSeek)
return buffer;

stream.Read(buffer, 0, count);
stream.Seek(0, SeekOrigin.Begin);
_Stream.Read(buffer, 0, _Count);
_Stream.Seek(0, SeekOrigin.Begin);
return buffer;
}
}
Expand Down
85 changes: 57 additions & 28 deletions EasyImgur/Form1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -320,24 +320,46 @@ private void UploadClipboard( bool _Anonymous )
private void UploadAlbum( bool _Anonymous, string[] _Paths, string _AlbumTitle )
{
ShowBalloonTip(2000, "Hold on...", "Attempting to upload album to Imgur (this may take a while)...", ToolTipIcon.None);
List<Image> images = new List<Image>();
List<string> titles = new List<string>();
List<string> descriptions = new List<string>();
int i = 0;

// Create the album
APIResponses.AlbumResponse album_response = ImgurAPI.CreateAlbum(_AlbumTitle, _Anonymous);
if (!album_response.Success)
{
ShowBalloonTip(2000, "Failed", "Could not create album (" + album_response.Status + "): " + album_response.ResponseData.Error, ToolTipIcon.None, true);
Statistics.GatherAndSend();
return;
}

// If we did manage to create the album we can now try to add images to it
int succeeded_count = 0;
int failed_count = 0;
int image_idx = 0;
Image album_thumbnail = null;

foreach (string path in _Paths)
{
// Instead of loading every file into memory, peek only their header to check if they are valid images
try
{
images.Add(Image.FromStream(new MemoryStream(File.ReadAllBytes(path))));
//ìmages.Add(System.Drawing.Image.FromStream(stream));
Image img = Image.FromStream(new MemoryStream(File.ReadAllBytes(path)));

string title = string.Empty;
string description = string.Empty;

FormattingHelper.FormattingContext format_context = new FormattingHelper.FormattingContext();
format_context.FilePath = path;
format_context.AlbumIndex = ++i;
titles.Add(GetTitleString(format_context));
descriptions.Add(GetDescriptionString(format_context));
format_context.AlbumIndex = ++image_idx;

APIResponses.ImageResponse resp = ImgurAPI.UploadImage(img, GetTitleString(format_context), GetDescriptionString(format_context), _Anonymous, ref album_response);

// If we haven't selected any thumbnail yet, or if the currently uploaded image has been turned into the cover image of the album, turn it into a thumbnail for the history view.
if (album_thumbnail == null || resp.ResponseData.Id == album_response.ResponseData.Cover)
album_thumbnail = img.GetThumbnailImage(pictureBoxHistoryThumb.Width, pictureBoxHistoryThumb.Height, null, System.IntPtr.Zero);

if (resp.Success)
succeeded_count++;
else
failed_count++;
}
catch (ArgumentException)
{
Expand All @@ -352,46 +374,53 @@ private void UploadAlbum( bool _Anonymous, string[] _Paths, string _AlbumTitle )
ShowBalloonTip(2000, "Failed", "Image is in use by another program (" + path + "):", ToolTipIcon.Error, true);
}
}
if (images.Count == 0)

// If no images managed to upload to the album we should delete it again
if (failed_count == _Paths.Count())
{
Log.Error("Album upload failed: No valid images in selected images!");
ShowBalloonTip(2000, "Failed", "Album upload cancelled: No valid images to upload!", ToolTipIcon.Error, true);
ShowBalloonTip(2000, "Album upload cancelled", "All images failed to upload! Check the log for more info.", ToolTipIcon.Error, true);

// Delete the album because we couldn't upload anything
ImgurAPI.DeleteAlbum(album_response.ResponseData.DeleteHash, _Anonymous);

Statistics.GatherAndSend();
return;
}
APIResponses.AlbumResponse response = ImgurAPI.UploadAlbum(images.ToArray(), _AlbumTitle, _Anonymous, titles.ToArray(), descriptions.ToArray());
if (response.Success)

// Did we succeed in uploading the album?
if (album_response.Success)
{
// clipboard calls can only be made on an STA thread, threading model is MTA when invoked from context menu
// Clipboard calls can only be made on an STA thread, threading model is MTA when invoked from context menu
if (System.Threading.Thread.CurrentThread.GetApartmentState() != System.Threading.ApartmentState.STA)
{
this.Invoke(new Action(() =>
Clipboard.SetText(Properties.Settings.Default.copyHttpsLinks
? response.ResponseData.Link.Replace("http://", "https://")
: response.ResponseData.Link)));
? album_response.ResponseData.Link.Replace("http://", "https://")
: album_response.ResponseData.Link)));
}
else
{
Clipboard.SetText(Properties.Settings.Default.copyHttpsLinks
? response.ResponseData.Link.Replace("http://", "https://")
: response.ResponseData.Link);
? album_response.ResponseData.Link.Replace("http://", "https://")
: album_response.ResponseData.Link);
}

ShowBalloonTip(2000, "Success!", Properties.Settings.Default.copyLinks ? "Link copied to clipboard" : "Upload placed in history: " + response.ResponseData.Link, ToolTipIcon.None);
ShowBalloonTip(2000, "Success!", Properties.Settings.Default.copyLinks ? "Link copied to clipboard" : "Upload placed in history: " + album_response.ResponseData.Link, ToolTipIcon.None);

HistoryItem item = new HistoryItem();
item.Timestamp = DateTime.Now;
item.Id = response.ResponseData.Id;
item.Link = response.ResponseData.Link;
item.Deletehash = response.ResponseData.DeleteHash;
item.Title = response.ResponseData.Title;
item.Description = response.ResponseData.Description;
item.Id = album_response.ResponseData.Id;
item.Link = album_response.ResponseData.Link;
item.Deletehash = album_response.ResponseData.DeleteHash;
item.Title = album_response.ResponseData.Title;
item.Description = album_response.ResponseData.Description;
item.Anonymous = _Anonymous;
item.Album = true;
item.Thumbnail = response.CoverImage.GetThumbnailImage(pictureBoxHistoryThumb.Width, pictureBoxHistoryThumb.Height, null, System.IntPtr.Zero);
item.Thumbnail = album_thumbnail;
Invoke(new Action(() => History.StoreHistoryItem(item)));
}
else
ShowBalloonTip(2000, "Failed", "Could not upload album (" + response.Status + "): " + response.ResponseData.Error, ToolTipIcon.None, true);
ShowBalloonTip(2000, "Failed", "Could not upload album (" + album_response.Status + "): " + album_response.ResponseData.Error, ToolTipIcon.None, true);

Statistics.GatherAndSend();
}
Expand Down
Loading

0 comments on commit 8876c9e

Please sign in to comment.