Skip to content

Commit 8e46d60

Browse files
committed
Add support for image attachment width/height information
1 parent f946a9e commit 8e46d60

11 files changed

+290
-196
lines changed

libsignal-service-dotnet/SignalServiceMessageReceiver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public Stream RetrieveProfileAvatar(string path, FileStream destination, byte[]
8383
/// <param name="tmpCipherDestination">The temporary destination for this attachment before decryption</param>
8484
/// <param name="maxSizeBytes">The maximum size for this attachment (not yet implemented)</param>
8585
/// <param name="listener">An optional listener (may be null) to receive callbacks on download progress.</param>
86-
public Stream RetrieveAttachment(SignalServiceAttachmentPointer pointer, Stream tmpCipherDestination, int maxSizeBytes, ProgressListener listener)
86+
public Stream RetrieveAttachment(SignalServiceAttachmentPointer pointer, Stream tmpCipherDestination, int maxSizeBytes, IProgressListener listener)
8787
{
8888
Socket.RetrieveAttachment(pointer.Relay, pointer.Id, tmpCipherDestination, maxSizeBytes);
8989
return AttachmentCipherInputStream.CreateFor(tmpCipherDestination, pointer.Size != null ? pointer.Size.Value : 0, pointer.Key, pointer.Digest);

libsignal-service-dotnet/SignalServiceMessageSender.cs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ private GroupContext CreateGroupContent(SignalServiceGroup group)
505505
if (group.Name != null) groupContext.Name = group.Name;
506506
if (group.Members != null ) groupContext.Members.AddRange(group.Members);
507507

508-
if (group.Avatar != null && group.Avatar.isStream())
508+
if (group.Avatar != null && group.Avatar.IsStream())
509509
{
510510
AttachmentPointer pointer = CreateAttachmentPointer(group.Avatar.AsStream());
511511
groupContext.Avatar = pointer;
@@ -602,14 +602,14 @@ private IList<AttachmentPointer> CreateAttachmentPointers(List<SignalServiceAtta
602602

603603
foreach (SignalServiceAttachment attachment in attachments)
604604
{
605-
if (attachment.isStream())
605+
if (attachment.IsStream())
606606
{
607607
Debug.WriteLine("Found attachment, creating pointer...", TAG);
608608
pointers.Add(CreateAttachmentPointer(attachment.AsStream()));
609609
}
610-
else if (attachment.isPointer())
610+
else if (attachment.IsPointer())
611611
{
612-
pointers.Add(CreateAttachmentPointerFromPointer(attachment.asPointer()));
612+
pointers.Add(CreateAttachmentPointerFromPointer(attachment.AsPointer()));
613613
}
614614
}
615615

@@ -619,13 +619,13 @@ private IList<AttachmentPointer> CreateAttachmentPointers(List<SignalServiceAtta
619619
private AttachmentPointer CreateAttachmentPointer(SignalServiceAttachmentStream attachment)
620620
{
621621
byte[] attachmentKey = Util.getSecretBytes(64);
622-
long paddedLength = PaddingInputStream.GetPaddedSize(attachment.getLength());
622+
long paddedLength = PaddingInputStream.GetPaddedSize(attachment.Length);
623623
long ciphertextLength = AttachmentCipherInputStream.GetCiphertextLength(paddedLength);
624624
PushAttachmentData attachmentData = new PushAttachmentData(attachment.getContentType(),
625-
new PaddingInputStream(attachment.getInputStream(), attachment.getLength()),
625+
new PaddingInputStream(attachment.InputStream, attachment.Length),
626626
ciphertextLength,
627627
new AttachmentCipherOutputStreamFactory(attachmentKey),
628-
attachment.getListener());
628+
attachment.Listener);
629629

630630
(ulong id, byte[] digest) = socket.SendAttachment(attachmentData);
631631

@@ -635,17 +635,27 @@ private AttachmentPointer CreateAttachmentPointer(SignalServiceAttachmentStream
635635
Id = id,
636636
Key = ByteString.CopyFrom(attachmentKey),
637637
Digest = ByteString.CopyFrom(digest),
638-
Size = (uint)attachment.getLength()
638+
Size = (uint)attachment.Length
639639
};
640640

641641
if (attachment.FileName != null)
642642
{
643643
attachmentPointer.FileName = attachment.FileName;
644644
}
645645

646-
if (attachment.getPreview().HasValue)
646+
if (attachment.Preview != null)
647647
{
648-
attachmentPointer.Thumbnail = ByteString.CopyFrom(attachment.getPreview().ForceGetValue());
648+
attachmentPointer.Thumbnail = ByteString.CopyFrom(attachment.Preview);
649+
}
650+
651+
if (attachment.Width > 0)
652+
{
653+
attachmentPointer.Width = (uint) attachment.Width;
654+
}
655+
656+
if (attachment.Height > 0)
657+
{
658+
attachmentPointer.Height = (uint)attachment.Height;
649659
}
650660

651661
if (attachment.VoiceNote)

libsignal-service-dotnet/crypto/SignalServiceCipher.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ private SignalServiceDataMessage CreateSignalServiceMessage(SignalServiceEnvelop
151151
envelope.getRelay(),
152152
pointer.SizeOneofCase == AttachmentPointer.SizeOneofOneofCase.Size ? pointer.Size : 0,
153153
pointer.ThumbnailOneofCase == AttachmentPointer.ThumbnailOneofOneofCase.Thumbnail ? pointer.Thumbnail.ToByteArray() : null,
154+
(int) pointer.Width, (int) pointer.Height,
154155
pointer.DigestOneofCase == AttachmentPointer.DigestOneofOneofCase.Digest ? pointer.Digest.ToByteArray() : null,
155156
pointer.FileNameOneofCase == AttachmentPointer.FileNameOneofOneofCase.FileName ? pointer.FileName : null,
156157
pointer.FlagsOneofCase == AttachmentPointer.FlagsOneofOneofCase.Flags && (pointer.Flags & (uint) AttachmentPointer.Types.Flags.VoiceMessage) != 0));
@@ -382,6 +383,7 @@ private SignalServiceGroup CreateGroupInfo(SignalServiceEnvelope envelope, DataM
382383
envelope.getRelay(),
383384
pointer.SizeOneofCase == AttachmentPointer.SizeOneofOneofCase.Size ? pointer.Size : 0,
384385
null,
386+
0, 0,
385387
pointer.DigestOneofCase == AttachmentPointer.DigestOneofOneofCase.Digest ? pointer.Digest.ToByteArray() : null,
386388
null,
387389
false);
Lines changed: 48 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,67 @@
1-
/**
2-
* Copyright (C) 2017 smndtrl, golf1052
3-
*
4-
* This program is free software: you can redistribute it and/or modify
5-
* it under the terms of the GNU General Public License as published by
6-
* the Free Software Foundation, either version 3 of the License, or
7-
* (at your option) any later version.
8-
*
9-
* This program is distributed in the hope that it will be useful,
10-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12-
* GNU General Public License for more details.
13-
*
14-
* You should have received a copy of the GNU General Public License
15-
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16-
*/
17-
181
using System;
192
using System.IO;
203

214
namespace libsignalservice.messages
22-
{
23-
public abstract class SignalServiceAttachment
5+
{
6+
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
7+
public abstract class SignalServiceAttachment
248
{
25-
private readonly String contentType;
9+
public String ContentType { get; }
2610

2711
internal SignalServiceAttachment(String contentType)
2812
{
29-
this.contentType = contentType;
13+
this.ContentType = contentType;
3014
}
3115

3216
public String getContentType()
3317
{
34-
return contentType;
18+
return ContentType;
3519
}
3620

37-
public abstract bool isStream();
21+
public abstract bool IsStream();
3822

39-
public abstract bool isPointer();
23+
public abstract bool IsPointer();
4024

4125
public SignalServiceAttachmentStream AsStream()
4226
{
4327
return (SignalServiceAttachmentStream)this;
4428
}
4529

46-
public SignalServiceAttachmentPointer asPointer()
30+
public SignalServiceAttachmentPointer AsPointer()
4731
{
4832
return (SignalServiceAttachmentPointer)this;
4933
}
5034

51-
public static Builder newStreamBuilder()
52-
{
53-
return new Builder();
54-
}
55-
5635
public class Builder
5736
{
58-
private Stream inputStream;
59-
private string contentType;
37+
private Stream InputStream;
38+
private string ContentType;
6039
private string FileName;
61-
private long length;
62-
private ProgressListener listener;
63-
private bool voiceNote;
40+
private long Length;
41+
private IProgressListener Listener;
42+
private bool VoiceNote;
43+
private int Width;
44+
private int Height;
6445

65-
internal Builder()
46+
Builder()
6647
{
6748
}
6849

69-
public Builder withStream(Stream inputStream)
50+
public Builder WithStream(Stream inputStream)
7051
{
71-
this.inputStream = inputStream;
52+
InputStream = inputStream;
7253
return this;
7354
}
7455

75-
public Builder withContentType(string contentType)
56+
public Builder WithContentType(string contentType)
7657
{
77-
this.contentType = contentType;
58+
ContentType = contentType;
7859
return this;
7960
}
8061

81-
public Builder withLength(long length)
62+
public Builder WithLength(long length)
8263
{
83-
this.length = length;
64+
Length = length;
8465
return this;
8566
}
8667

@@ -90,45 +71,58 @@ public Builder WithFileName(string fileName)
9071
return this;
9172
}
9273

93-
public Builder withListener(ProgressListener listener)
74+
public Builder WithListener(IProgressListener listener)
9475
{
95-
this.listener = listener;
76+
Listener = listener;
9677
return this;
9778
}
9879

99-
public Builder withVoiceNote(bool voiceNote)
80+
public Builder WithVoiceNote(bool voiceNote)
10081
{
101-
this.voiceNote = voiceNote;
82+
VoiceNote = voiceNote;
10283
return this;
84+
}
85+
86+
public Builder WithWidth(int width)
87+
{
88+
Width = width;
89+
return this;
90+
}
91+
92+
public Builder WithHeight(int height)
93+
{
94+
Height = height;
95+
return this;
10396
}
10497

105-
public SignalServiceAttachmentStream build()
98+
public SignalServiceAttachmentStream Build()
10699
{
107-
if (inputStream == null)
100+
if (InputStream == null)
108101
{
109102
throw new ArgumentException("Must specify stream!");
110103
}
111-
if (contentType == null)
104+
if (ContentType == null)
112105
{
113106
throw new ArgumentException("No content type specified!");
114107
}
115-
if (length == 0)
108+
if (Length == 0)
116109
{
117110
throw new ArgumentException("No length specified!");
118111
}
119112

120-
return new SignalServiceAttachmentStream(inputStream, contentType, (uint)length, FileName, voiceNote, listener);
113+
return new SignalServiceAttachmentStream(InputStream, ContentType, (uint)Length, FileName, VoiceNote, null, Width, Height, Listener);
121114
}
122115
}
123116

124-
public interface ProgressListener
117+
public interface IProgressListener
125118
{
126119
/// <summary>
127120
/// Called on a progress change event.
128121
/// </summary>
129122
/// <param name="total">The total amount of transmit/receive in bytes.</param>
130123
/// <param name="progress">The amount that has been transmitted/received in bytes thus far</param>
131-
void onAttachmentProgress(long total, long progress);
124+
void OnAttachmentProgress(long total, long progress);
132125
}
133-
}
126+
}
127+
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
134128
}
Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,50 @@
11
using System.IO;
22

3-
namespace libsignalservice.messages
4-
{
5-
/// <summary>
6-
/// Represents a received SignalServiceAttachment "handle." This
7-
/// is a pointer to the actual attachment content, which needs to be
8-
/// retrieved using <see cref="SignalServiceMessageReceiver.RetrieveAttachment(SignalServiceAttachmentPointer, Stream, int, ProgressListener)"/>
3+
namespace libsignalservice.messages
4+
{
5+
/// <summary>
6+
/// Represents a received SignalServiceAttachment "handle." This
7+
/// is a pointer to the actual attachment content, which needs to be
8+
/// retrieved using <see cref="SignalServiceMessageReceiver.RetrieveAttachment(SignalServiceAttachmentPointer, Stream, int, IProgressListener)"/>
99
/// </summary>
10-
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
11-
public class SignalServiceAttachmentPointer : SignalServiceAttachment
10+
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
11+
public class SignalServiceAttachmentPointer : SignalServiceAttachment
1212
{
13-
1413
public ulong Id { get; }
15-
public byte[] Key { get; }
16-
public string Relay { get; }
17-
public uint? Size { get; }
18-
public byte[] Preview { get; }
19-
public byte[] Digest { get; }
20-
public string FileName { get; }
21-
public bool VoiceNote { get; }
22-
23-
public SignalServiceAttachmentPointer(ulong id, string contentType, byte[] key, string relay, uint? size, byte[] preview, byte[] digest, string fileName, bool voiceNote)
24-
: base(contentType)
25-
{
26-
Id = id;
27-
Key = key;
28-
Relay = relay;
29-
Size = size;
30-
Preview = preview;
31-
Digest = digest;
32-
FileName = fileName;
33-
VoiceNote = voiceNote;
34-
}
35-
36-
public override bool isStream()
37-
{
38-
return false;
39-
}
40-
41-
public override bool isPointer()
42-
{
43-
return true;
44-
}
14+
public byte[] Key { get; }
15+
public string Relay { get; }
16+
public uint? Size { get; }
17+
public byte[] Preview { get; }
18+
public byte[] Digest { get; }
19+
public string FileName { get; }
20+
public bool VoiceNote { get; }
21+
public int Width { get; }
22+
public int Height { get; }
23+
24+
public SignalServiceAttachmentPointer(ulong id, string contentType, byte[] key, string relay, uint? size, byte[] preview, int width, int height, byte[] digest, string fileName, bool voiceNote)
25+
: base(contentType)
26+
{
27+
Id = id;
28+
Key = key;
29+
Relay = relay;
30+
Size = size;
31+
Preview = preview;
32+
Digest = digest;
33+
FileName = fileName;
34+
VoiceNote = voiceNote;
35+
Width = width;
36+
Height = height;
37+
}
38+
39+
public override bool IsStream()
40+
{
41+
return false;
42+
}
43+
44+
public override bool IsPointer()
45+
{
46+
return true;
47+
}
4548
}
46-
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
47-
}
49+
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
50+
}

0 commit comments

Comments
 (0)