Skip to content

Commit

Permalink
Merge pull request #9 from paw3lx/feature/upgrate-imagesharp-302
Browse files Browse the repository at this point in the history
Upgrate imagesharp 3.0.2
  • Loading branch information
paw3lx authored Nov 3, 2023
2 parents 7d21b4e + a323a08 commit ed0305c
Show file tree
Hide file tree
Showing 14 changed files with 94 additions and 168 deletions.
3 changes: 3 additions & 0 deletions src/StegoCoreLib/Algorithms/IStegoAlgorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ namespace StegoCore.Algorithms;
public interface IStegoAlgorithm
{
Image<Rgba32> Embed(Image<Rgba32> baseImage, SecretData secret, Settings settings = null);

byte[] Decode(Image<Rgba32> stegoImage, Settings settings = null);

int ReadSecretLength(Image<Rgba32> stegoImage, Settings settings = null);

bool IsEmbedPossible(Image<Rgba32> image, int secretLength);
}
12 changes: 6 additions & 6 deletions src/StegoCoreLib/Algorithms/Lsb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public override Image<Rgba32> Embed(Image<Rgba32> baseImage, SecretData secret,
if (occupied.Contains(pair))
continue;
occupied.Add(pair);
var pixel = baseImage[width, height];
Rgba32 pixel = baseImage[width, height];
pixel.R = SetLsb(pixel.R, secretBits[index]);
pixel.B = SetLsb(pixel.B, secretBits[index + 1]);
baseImage[width, height] = pixel;
Expand Down Expand Up @@ -64,7 +64,7 @@ private BitArray ReadBits(Image<Rgba32> stegoImage, int start, int end, string k
BitArray bits = new BitArray(length);
int index = 0;
Random random = GetRandomGenenator(key);
List<Tuple<int, int>> occupied = new List<Tuple<int, int>>();
List<Tuple<int, int>> occupied = new();
while (index < end)
{
int width = random.Next(stegoImage.Width);
Expand All @@ -78,7 +78,7 @@ private BitArray ReadBits(Image<Rgba32> stegoImage, int start, int end, string k
index += 2;
continue;
}
var pixel = stegoImage[width, height];
Rgba32 pixel = stegoImage[width, height];
(bool bitR, bool bitB) = GetBitsFromPixel(pixel);
bits.Set(index - start, bitR);
bits.Set(index - start + 1, bitB);
Expand All @@ -90,8 +90,8 @@ private BitArray ReadBits(Image<Rgba32> stegoImage, int start, int end, string k

private (bool R, bool B) GetBitsFromPixel(Rgba32 pixel)
{
var r = pixel.R;
var b = pixel.B;
byte r = pixel.R;
byte b = pixel.B;
bool bitR = GetBit(r, 0);
bool bitB = GetBit(b, 0);
return (bitR, bitB);
Expand All @@ -104,7 +104,7 @@ private static bool GetBit(byte b, int bitNumber)

private static byte SetLsb(byte b, bool value)
{
byte ret = b;
byte ret;
if (value)
ret = (byte)(b | 1); // Make LSB 1
else
Expand Down
4 changes: 2 additions & 2 deletions src/StegoCoreLib/Algorithms/StegoAlgorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ public abstract class StegoAlgorithm : IStegoAlgorithm
/// <returns>secret length</returns>
public abstract int ReadSecretLength(Image<Rgba32> stegoImage, Settings settings = null);

internal Random GetRandomGenenator(Settings settings)
internal static Random GetRandomGenenator(Settings settings)
{
return GetRandomGenenator(settings?.Key);
}

internal Random GetRandomGenenator(string seed)
internal static Random GetRandomGenenator(string seed)
{
return new Random((seed ?? string.Empty).GetHashCode());
}
Expand Down
84 changes: 22 additions & 62 deletions src/StegoCoreLib/Algorithms/ZhaoKoch.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using StegoCore.Core;
Expand All @@ -15,13 +12,13 @@ namespace StegoCore.Algorithms;

public class ZhaoKoch : StegoAlgorithm
{
private int d;
private int _d;
public override Image<Rgba32> Embed(Image<Rgba32> baseImage, SecretData secret, Settings settings = null)
{
BitArray secretBits = secret.SecretWithLengthBits;
if (IsEmbedPossible(baseImage, secretBits.Length) == false)
throw new InvalidDataException("Secret data is to big for embending.");
d = settings?.D ?? 5;
_d = settings?.D ?? 5;
int width = 0;
int height = 0;
int index = 0;
Expand All @@ -36,9 +33,9 @@ public override Image<Rgba32> Embed(Image<Rgba32> baseImage, SecretData secret,
{
break;
}
var luminanceMatrix = GetLuminanceMatrix(baseImage, width, height);
var yMatrix = luminanceMatrix.GetY();
var matrixWithBit = InsertOneBit(yMatrix, secretBits.Get(index), d);
PixelLuma[][] luminanceMatrix = GetLuminanceMatrix(baseImage, width, height);
float[][] yMatrix = luminanceMatrix.GetY();
float[][] matrixWithBit = InsertOneBit(yMatrix, secretBits.Get(index), _d);
luminanceMatrix = luminanceMatrix.SetY(matrixWithBit);
SetLuminance(baseImage, luminanceMatrix, width, height);
index++;
Expand All @@ -59,7 +56,7 @@ public override byte[] Decode(Image<Rgba32> stegoImage, Settings settings = null
int length = ReadSecretLength(stegoImage, settings) * 8;
if (length <= 0 || !IsEmbedPossible(stegoImage, length))
throw new DecodeException($"Cannot read secret from this image file. Readed secret length: {length}");
d = settings?.D ?? 5;
_d = settings?.D ?? 5;
BitArray bits = ReadBits(stegoImage, this.SecretDataLength, length + this.SecretDataLength);
return bits.ToByteArray();

Expand Down Expand Up @@ -99,9 +96,9 @@ private BitArray ReadBits(Image<Rgba32> stegoImage, int start, int end)
width += 8;
continue;
}
var luminanceMatrix = GetLuminanceMatrix(stegoImage, width, height);
var yMatrix = luminanceMatrix.GetY();
var bit = ReadOneBit(yMatrix, d);
PixelLuma[][] luminanceMatrix = GetLuminanceMatrix(stegoImage, width, height);
float[][] yMatrix = luminanceMatrix.GetY();
bool bit = ReadOneBit(yMatrix, _d);
bits.Set(index - start, bit);
index++;
width += 8;
Expand All @@ -110,7 +107,7 @@ private BitArray ReadBits(Image<Rgba32> stegoImage, int start, int end)
return bits;
}

private PixelLuma[][] GetLuminanceMatrix(Image<Rgba32> pixels, int width, int height)
private static PixelLuma[][] GetLuminanceMatrix(Image<Rgba32> pixels, int width, int height)
{
int i, j;
PixelLuma[][] luminance = new PixelLuma[8][];
Expand All @@ -119,23 +116,23 @@ private PixelLuma[][] GetLuminanceMatrix(Image<Rgba32> pixels, int width, int he
luminance[i] = new PixelLuma[8];
for (j = 0; j < 8; j++)
{
var pixel = pixels[width + i, height + j];
PixelLuma luma = new PixelLuma(pixel.R, pixel.G, pixel.B);
Rgba32 pixel = pixels[width + i, height + j];
PixelLuma luma = new(pixel.R, pixel.G, pixel.B);
luminance[i][j] = luma;
}
}
return luminance;
}

private void SetLuminance(Image<Rgba32> pixels, PixelLuma[][] luminanceMatrix, int width, int height)
private static void SetLuminance(Image<Rgba32> pixels, PixelLuma[][] luminanceMatrix, int width, int height)
{
int i, j;
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
var pixel = pixels[width + i, height + j];
var luma = luminanceMatrix[i][j];
Rgba32 pixel = pixels[width + i, height + j];
PixelLuma luma = luminanceMatrix[i][j];
pixel.R = luma.R;
pixel.G = luma.G;
pixel.B = luma.B;
Expand All @@ -146,7 +143,7 @@ private void SetLuminance(Image<Rgba32> pixels, PixelLuma[][] luminanceMatrix, i

public float[][] InsertOneBit(float[][] matrix, bool bit, float d)
{
float[][] quantizeMatrix = (Dct(matrix));
float[][] quantizeMatrix = Dct(matrix);

float k1 = quantizeMatrix[3][4];
float k2 = quantizeMatrix[4][3];
Expand All @@ -173,58 +170,21 @@ public float[][] InsertOneBit(float[][] matrix, bool bit, float d)
}
quantizeMatrix[3][4] = k1;
quantizeMatrix[4][3] = k2;
float[][] outMatrix = DctInv((quantizeMatrix));
float[][] outMatrix = DctInv(quantizeMatrix);
return outMatrix;
}

private bool ReadOneBit(float[][] matrix, float d)
{
float[][] quantized = (Dct(matrix));
float[][] quantized = Dct(matrix);
float k1 = quantized[3][4];
float k2 = quantized[4][3];
if (Math.Abs(k1) - Math.Abs(k2) < -d)
return true;
return false;
}


public float[][] Quantize(float[][] matrix)
{
if (matrix.Length != 8 || matrix.Any(x => x.Length != 8))
throw new InvalidDataException("Matrix width and height are not equal 8");
int i, j;

float[][] quantizeMatrix = new float[8][];
for (i = 0; i < 8; i++)
{
quantizeMatrix[i] = new float[8];
for (j = 0; j < 8; j++)
{
quantizeMatrix[i][j] = matrix[i][j] / Statics.JPEG.JpegLuminQuantTable[i][j];
}
}
return quantizeMatrix;
}

public float[][] Dequantize(float[][] quantizedMatrix)
{
if (quantizedMatrix.Length != 8 || quantizedMatrix.Any(x => x.Length != 8))
throw new InvalidDataException("Matrix width and height are not equal 8");
int i, j;

float[][] matrix = new float[8][];
for (i = 0; i < 8; i++)
{
matrix[i] = new float[8];
for (j = 0; j < 8; j++)
{
matrix[i][j] = quantizedMatrix[i][j] * Statics.JPEG.JpegLuminQuantTable[i][j];
}
}
return matrix;
}

public float[][] Dct(float[][] baseMatrix)
public static float[][] Dct(float[][] baseMatrix)
{
if (baseMatrix.Length != baseMatrix[0].Length)
throw new InvalidDataException("Matrix width and height are different");
Expand Down Expand Up @@ -263,7 +223,7 @@ public float[][] Dct(float[][] baseMatrix)
return dctMatrix;
}

public float[][] DctInv(float[][] dct)
public static float[][] DctInv(float[][] dct)
{
if (dct.Length != dct[0].Length)
throw new InvalidDataException("Matrix width and height are different");
Expand All @@ -284,8 +244,8 @@ public float[][] DctInv(float[][] dct)
for (v = 0; v < length; v++)
{
var t = dct[u][v] * (float)Math.Cos(u * (x + 0.5) * Math.PI / 8) * (float)Math.Cos(v * (y + 0.5) * Math.PI / 8);
if (u == 0) t *= (1 / (float)Math.Sqrt(2));
if (v == 0) t *= (1 / (float)Math.Sqrt(2));
if (u == 0) t *= 1 / (float)Math.Sqrt(2);
if (v == 0) t *= 1 / (float)Math.Sqrt(2);
ammount += t;
}
}
Expand Down
24 changes: 9 additions & 15 deletions src/StegoCoreLib/Core/SecretData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,19 @@ public class SecretData
{
public SecretData(byte[] fileBytes)
{
this.fileBytes = fileBytes;
this.fileLength = fileBytes.Length;
var lengthBytes = BitConverter.GetBytes(this.fileLength); // length 4 = 32 bits
secretWithLength = lengthBytes.Concat(fileBytes);
FileBytes = fileBytes;
FileLength = fileBytes.Length;
byte[] lengthBytes = BitConverter.GetBytes(this.FileLength); // length 4 = 32 bits
FileWithLengthBytes = lengthBytes.Concat(fileBytes);
}

private byte[] fileBytes;
private int fileLength;
private IEnumerable<byte> secretWithLength;

public int FileLength => fileLength;
public byte[] FileBytes => fileBytes;
public IEnumerable<byte> FileWithLengthBytes => secretWithLength;

public BitArray SecretWithLengthBits => new BitArray(secretWithLength.ToArray());

public BitArray SecretBits => new BitArray(fileBytes);
public int FileLength { get; }

public byte[] FileBytes { get; }

public IEnumerable<byte> FileWithLengthBytes { get; }

public BitArray SecretWithLengthBits => new(FileWithLengthBytes.ToArray());

public BitArray SecretBits => new(FileBytes);
}
8 changes: 3 additions & 5 deletions src/StegoCoreLib/Core/StegoBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Collections;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using StegoCore.Extensions;
Expand All @@ -8,7 +7,7 @@ namespace StegoCore.Core;

public abstract class StegoBase : IStegoEntry
{
private bool disposedValue = false;
private bool _disposedValue = false;
protected Image<Rgba32> image;
protected SecretData secretData;
protected Settings settings;
Expand All @@ -18,13 +17,13 @@ public abstract class StegoBase : IStegoEntry

protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
if (!_disposedValue)
{
if (disposing)
{
image?.Dispose();
}
disposedValue = true;
_disposedValue = true;
}
}

Expand All @@ -42,5 +41,4 @@ void System.IDisposable.Dispose()
{
Dispose(true);
}

}
19 changes: 9 additions & 10 deletions src/StegoCoreLib/Core/StegoEntry.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
using System.IO;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;

namespace StegoCore.Core;

public class StegoEntry : StegoBase
{
public StegoEntry(Stream imageStream, Stream secretData)
{
image = Image.Load(imageStream);
this.LoadSecretData(secretData);
image = Image.Load<Rgba32>(imageStream);
LoadSecretData(secretData);
}

public StegoEntry(string imagePath)
{
image = Image.Load(imagePath);
image = Image.Load<Rgba32>(imagePath);

}

public StegoEntry(byte[] imageBytes)
{
image = Image.Load(imageBytes);
image = Image.Load<Rgba32>(imageBytes);
}

public void SaveImage(string path)
Expand All @@ -36,25 +37,23 @@ public void SaveImage(MemoryStream stream)
protected void LoadSecretData(string filePath)
{
byte[] buffer = null;
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using (FileStream fs = new(filePath, FileMode.Open, FileAccess.Read))
{
buffer = new byte[fs.Length];
fs.Read(buffer, 0, (int)fs.Length);
}
this.secretData = new SecretData(buffer);
secretData = new SecretData(buffer);
}

protected void LoadSecretData(Stream stream)
{
byte[] buffer = null;
stream.Read(buffer, 0, (int)stream.Length);
this.secretData = new SecretData(buffer);
secretData = new SecretData(buffer);
}

protected void LoadSecretData(byte[] bytes)
{
this.secretData = new SecretData(bytes);
secretData = new SecretData(bytes);
}


}
Loading

0 comments on commit ed0305c

Please sign in to comment.