Skip to content

Commit

Permalink
working jsteg coder
Browse files Browse the repository at this point in the history
  • Loading branch information
NullExceptionTSB committed Apr 14, 2023
1 parent c1c4aff commit 0ebe29b
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 140 deletions.
35 changes: 20 additions & 15 deletions psteg-stegano/Engine/Encode/JpegEncoderEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
namespace psteg.Stegano.Engine.Encode {
public abstract class JpegCoderOptions {
private const int DEPTH_MAX = 10;
public const int DEFAULT_SUB_DEPTH = 4;
public const int DEFAULT_INS_DEPTH = 2;
public const bool ALLOW_INSERT = false;

private int _maxSubstituteDepth = 4;
private int _maxInsertDepth = 2;

Expand All @@ -35,7 +39,7 @@ public abstract class JpegCoderOptions {

public bool InsertInZRL { get; set; } = false;
}
public sealed class JstegDecoderOptions : JpegCoderOptions { }
public sealed class JstegCoderOptions : JpegCoderOptions { }

public sealed class JpegEncoderEngine<T> : EncoderEngine where T : JpegCoderOptions {
public enum Algorithm {
Expand All @@ -49,7 +53,7 @@ public enum Algorithm {
public string Seed { get; set; }
public bool ReverseBitOrder { get; set; }

private JstegDecoderOptions JstegOpts;
private JstegCoderOptions JstegOpts;

private JpegCodec Codec;

Expand Down Expand Up @@ -88,7 +92,8 @@ public enum Algorithm {
bool pop_bq_ret;
int zrl_ammt = 0;
while ((pop_bq_ret = PopulateBq()) || (bq.Length > 0)) {
if (zrl_ammt-- > 0) {
if (zrl_ammt > 0) {
zrl_ammt--;
Codec.WriteNextCode(CodeGen(LSB.WidthPop(JstegOpts.MaxInsertDepth, bq), JstegOpts.MaxInsertDepth));
continue;
}
Expand All @@ -102,7 +107,7 @@ public enum Algorithm {

if (code.JpegIsAC) {
byte zrl = (byte)((code.Length & 0xF0) >> 4),
len = (byte) (code.Length & 0xF0);
len = (byte) (code.Length & 0x0F);

if (JstegOpts.InsertInZRL && zrl > 0) {
zrl_ammt = zrl;
Expand All @@ -123,27 +128,31 @@ public enum Algorithm {
//lsb substitute
int sublen = Math.Min(JstegOpts.MaxSubstituteDepth, code.Length);
Codec.WriteNextCode(CodeMix(code, LSB.WidthPop(sublen, bq), sublen));
}
} else
Codec.WriteNextCode(code);
}

Codec.WriteNextCode(code);
}

if (zrl_ammt > 0)
Codec.WriteNextCode(new Code(zrl_ammt<<4, 0));
}

public override void Go() {

Codec = new JpegCodec(CoverStream, OutputStream);
Codec.SetScanRead(0);
Codec.InitScanWrite();

Prepare();
Exception e=null;
try {
// try {
switch (DistributionAlgo) {
case Algorithm.Jsteg:
JstegEncode();
break;
}
Codec.CopyRestOfScan();
} catch (Exception ex) { e=ex; }
//} catch (Exception ex) { e=ex; }

Codec.CloseScanWrite();
Finish();
Expand All @@ -153,14 +162,10 @@ public enum Algorithm {
}

public JpegEncoderEngine(JpegCoderOptions opts = null) : base() {
if (typeof(T) == typeof(JstegDecoderOptions)) {
if (typeof(T) == typeof(JstegCoderOptions)) {
DistributionAlgo = Algorithm.Jsteg;
JstegOpts = (JstegDecoderOptions)opts;
JstegOpts = (JstegCoderOptions)opts;
}

Codec = new JpegCodec(CoverStream, OutputStream);
Codec.SetScanRead(0);
Codec.InitScanWrite();
}
}
}
16 changes: 8 additions & 8 deletions psteg-stegano/Engine/Encode/LSBEncoderEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ public sealed class LSBEncoderEngine : EncoderEngine{
//last block detection for coprimes
if (remainder == bq.Length && (!data_in_stream)) {
byte d = state.Get();
d = LSB.Mix(d, (byte)LSB.WidthPop(remainder, bq), cover_mask);
d = LSB.Mix(d, (byte)LSB.WidthPopUnsafe(remainder, bq), cover_mask);
state.Set(d);
} else {
byte d = state.Get();
d = LSB.Mix(d, (byte)LSB.WidthPop(BitWidth, bq), cover_mask);
d = LSB.Mix(d, (byte)LSB.WidthPopUnsafe(BitWidth, bq), cover_mask);
state.Set(d);
}

Expand Down Expand Up @@ -136,12 +136,12 @@ public sealed class LSBEncoderEngine : EncoderEngine{
}

if (mono)
smp_buffer[smp_buffer_pos] = LSB.Mix(smp_buffer[smp_buffer_pos++], (byte)LSB.WidthPop(BitWidth, bq), cover_mask);
smp_buffer[smp_buffer_pos] = LSB.Mix(smp_buffer[smp_buffer_pos++], (byte)LSB.WidthPopUnsafe(BitWidth, bq), cover_mask);
else {
if (AudioSpecificOptions.Channels['L'])
smp_buffer[smp_buffer_pos] = LSB.Mix(smp_buffer[smp_buffer_pos], (byte)LSB.WidthPop(BitWidth, bq), cover_mask);
smp_buffer[smp_buffer_pos] = LSB.Mix(smp_buffer[smp_buffer_pos], (byte)LSB.WidthPopUnsafe(BitWidth, bq), cover_mask);
if (AudioSpecificOptions.Channels['R'])
smp_buffer[smp_buffer_pos+1] = LSB.Mix(smp_buffer[smp_buffer_pos+1], (byte)LSB.WidthPop(BitWidth, bq), cover_mask);
smp_buffer[smp_buffer_pos+1] = LSB.Mix(smp_buffer[smp_buffer_pos+1], (byte)LSB.WidthPopUnsafe(BitWidth, bq), cover_mask);
smp_buffer_pos += 2;
}

Expand Down Expand Up @@ -217,12 +217,12 @@ public sealed class LSBEncoderEngine : EncoderEngine{
}

if (mono)
smp_buffer[smp_buffer_pos] = LSB.Mix(smp_buffer[smp_buffer_pos++], (ushort)LSB.WidthPop(BitWidth, bq), cover_mask);
smp_buffer[smp_buffer_pos] = LSB.Mix(smp_buffer[smp_buffer_pos++], (ushort)LSB.WidthPopUnsafe(BitWidth, bq), cover_mask);
else {
if (AudioSpecificOptions.Channels['L'])
smp_buffer[smp_buffer_pos] = LSB.Mix(smp_buffer[smp_buffer_pos], (ushort)LSB.WidthPop(BitWidth, bq), cover_mask);
smp_buffer[smp_buffer_pos] = LSB.Mix(smp_buffer[smp_buffer_pos], (ushort)LSB.WidthPopUnsafe(BitWidth, bq), cover_mask);
if (AudioSpecificOptions.Channels['R'])
smp_buffer[smp_buffer_pos+1] = LSB.Mix(smp_buffer[smp_buffer_pos+1], (ushort)LSB.WidthPop(BitWidth, bq), cover_mask);
smp_buffer[smp_buffer_pos+1] = LSB.Mix(smp_buffer[smp_buffer_pos+1], (ushort)LSB.WidthPopUnsafe(BitWidth, bq), cover_mask);
smp_buffer_pos += 2;
}

Expand Down
3 changes: 1 addition & 2 deletions psteg-stegano/Engine/Factory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ public sealed class EncoderFactory {

public static EncoderFactory Create(Methods method, object extra = null) {
EncoderFactory ef = new EncoderFactory();
Type et = extra.GetType();
switch (method) {
case Methods.DCT:
ef.Engine = (EncoderEngine)Activator.CreateInstance(et.GetType().MakeGenericType(typeof(JpegCoderOptions)), new object[] { extra });
ef.Engine = (EncoderEngine)Activator.CreateInstance(typeof(JpegEncoderEngine<>).MakeGenericType(extra.GetType()), new object[] { extra });
break;
case Methods.Metadata:
ef.Engine = new MetadataEncoderEngine();
Expand Down
11 changes: 10 additions & 1 deletion psteg-stegano/Engine/Util/LSB.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,22 @@ public static class LSB {
bq.Push((data&(1<<i))>0);
}

public static int WidthPop(int depth, BitQueue bq) {
public static int WidthPopUnsafe(int depth, BitQueue bq) {
int r = 0;
for (int i = 0; i < depth; i++)
r |= ((bq.PopSingle() ? 1 : 0) << i);
return r;
}

public static int WidthPop(int depth, BitQueue bq) {
int r = 0;
for (int i = 0; i < depth; i++) {
if (bq.Length > 0)
r |= ((bq.PopSingle() ? 1 : 0) << i);
}
return r;
}

public static class SpecificOptions {
public struct Img {
[System.Obsolete]
Expand Down
Loading

0 comments on commit 0ebe29b

Please sign in to comment.