Commit 427f5a63 authored by BORNON Théophile's avatar BORNON Théophile

Ajouts des commentaires et de la solution de tests

parent ceb25754
...@@ -5,6 +5,8 @@ VisualStudioVersion = 15.0.27004.2010 ...@@ -5,6 +5,8 @@ VisualStudioVersion = 15.0.27004.2010
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessing", "S04_Projet\ImageProcessing.csproj", "{229D3602-654B-498B-9478-5CC3982C358C}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessing", "S04_Projet\ImageProcessing.csproj", "{229D3602-654B-498B-9478-5CC3982C358C}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Image_Processing_Test", "Tests\Image_Processing_Test.csproj", "{55E3E9D6-F5C5-47AD-851C-EE55CCE639F6}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
...@@ -15,6 +17,10 @@ Global ...@@ -15,6 +17,10 @@ Global
{229D3602-654B-498B-9478-5CC3982C358C}.Debug|Any CPU.Build.0 = Debug|Any CPU {229D3602-654B-498B-9478-5CC3982C358C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{229D3602-654B-498B-9478-5CC3982C358C}.Release|Any CPU.ActiveCfg = Release|Any CPU {229D3602-654B-498B-9478-5CC3982C358C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{229D3602-654B-498B-9478-5CC3982C358C}.Release|Any CPU.Build.0 = Release|Any CPU {229D3602-654B-498B-9478-5CC3982C358C}.Release|Any CPU.Build.0 = Release|Any CPU
{55E3E9D6-F5C5-47AD-851C-EE55CCE639F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{55E3E9D6-F5C5-47AD-851C-EE55CCE639F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{55E3E9D6-F5C5-47AD-851C-EE55CCE639F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{55E3E9D6-F5C5-47AD-851C-EE55CCE639F6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
......
using System; using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Threading;
namespace S04_Projet namespace S04_Projet
{ {
...@@ -22,7 +20,7 @@ namespace S04_Projet ...@@ -22,7 +20,7 @@ namespace S04_Projet
GrayScaleLuminosity, GrayScaleLuminosity,
Superposition, Superposition,
Filter, Filter,
//CreateImage, Steganography,
Histogram, Histogram,
Dithering, Dithering,
Debug, Debug,
...@@ -30,6 +28,9 @@ namespace S04_Projet ...@@ -30,6 +28,9 @@ namespace S04_Projet
Save Save
} }
/// <summary>
/// Liste des noms des éléments du menu
/// </summary>
private static string[] menuItems = new string[] private static string[] menuItems = new string[]
{ {
"Agrandir l'image", "Agrandir l'image",
...@@ -41,6 +42,7 @@ namespace S04_Projet ...@@ -41,6 +42,7 @@ namespace S04_Projet
"Passage à une image en nuances de gris (luminosité)", "Passage à une image en nuances de gris (luminosité)",
"Superposer avec une autre image", "Superposer avec une autre image",
"Ajouter un filtre de convolution", "Ajouter un filtre de convolution",
"Stéganographie",
"Générer les histogrammes de l'image", "Générer les histogrammes de l'image",
"Floyd-Steinberg dithering", "Floyd-Steinberg dithering",
"Activer le mode debug", "Activer le mode debug",
...@@ -54,6 +56,7 @@ namespace S04_Projet ...@@ -54,6 +56,7 @@ namespace S04_Projet
private static Stopwatch sw = new Stopwatch(); private static Stopwatch sw = new Stopwatch();
private static Menu mainMenu = new Menu(menuItems); private static Menu mainMenu = new Menu(menuItems);
private static Menu filterMenu = new Menu(Filter.Noms); private static Menu filterMenu = new Menu(Filter.Noms);
private static Menu steganoMenu = new Menu(new string[] { "Ajouter un message caché", "Lire un message caché" });
/// <summary> /// <summary>
/// Charge l'image /// Charge l'image
...@@ -115,7 +118,12 @@ namespace S04_Projet ...@@ -115,7 +118,12 @@ namespace S04_Projet
} }
#region Operations #region Operations
/// <summary>
/// Effectue l'opération passée en paramètre sur l'image donnée
/// </summary>
/// <param name="ope">Opération</param>
/// <param name="img">Image</param>
/// <returns>Image avec l'opération effectuée. Retourne null si l'utilisateur sauvegarde l'image</returns>
public static MyImage PerformOperation(Operation ope, MyImage img) public static MyImage PerformOperation(Operation ope, MyImage img)
{ {
MyImage output = null; MyImage output = null;
...@@ -147,9 +155,12 @@ namespace S04_Projet ...@@ -147,9 +155,12 @@ namespace S04_Projet
case Operation.Superposition: case Operation.Superposition:
output = SuperpositionOperation(img); output = SuperpositionOperation(img);
break; break;
case Operation.Filter: // TODO case Operation.Filter:
output = FilterOperation(img); output = FilterOperation(img);
break; break;
case Operation.Steganography:
output = SteganographyOperation(img);
break;
case Operation.Histogram: case Operation.Histogram:
output = HistogramOperation(img); output = HistogramOperation(img);
break; break;
...@@ -175,6 +186,11 @@ namespace S04_Projet ...@@ -175,6 +186,11 @@ namespace S04_Projet
return output; return output;
} }
/// <summary>
/// Applique un aggrandissement d'un facteur spécifié par l'utilisateur sur une image donnée
/// </summary>
/// <param name="img">Image</param>
/// <returns>Image modifiée</returns>
public static MyImage EnlargeOperation(MyImage img) public static MyImage EnlargeOperation(MyImage img)
{ {
int coeff = 0; int coeff = 0;
...@@ -188,6 +204,11 @@ namespace S04_Projet ...@@ -188,6 +204,11 @@ namespace S04_Projet
return img.Enlarge(coeff); return img.Enlarge(coeff);
} }
/// <summary>
/// Applique un rétrécissement d'un facteur spécifié par l'utilisateur sur une image donnée
/// </summary>
/// <param name="img">Image</param>
/// <returns>Image modifiée</returns>
public static MyImage ShrinkOperation(MyImage img) public static MyImage ShrinkOperation(MyImage img)
{ {
int coeff = 0; int coeff = 0;
...@@ -201,6 +222,12 @@ namespace S04_Projet ...@@ -201,6 +222,12 @@ namespace S04_Projet
return img.Shrink(coeff); return img.Shrink(coeff);
} }
/// <summary>
/// Applique un filtre gris sur une image donnée
/// </summary>
/// <param name="img">Image</param>
/// <param name="ope">Type de filtre gris</param>
/// <returns>Image modifiée</returns>
public static MyImage GrayOperation(MyImage img, Operation ope) public static MyImage GrayOperation(MyImage img, Operation ope)
{ {
int nbScale = 0; int nbScale = 0;
...@@ -216,6 +243,11 @@ namespace S04_Projet ...@@ -216,6 +243,11 @@ namespace S04_Projet
else return img.ToGrayScale((byte)nbScale, MyImage.GrayFilterType.LUMINOSITY); else return img.ToGrayScale((byte)nbScale, MyImage.GrayFilterType.LUMINOSITY);
} }
/// <summary>
/// Superpose une image spécifiée par l'utilisateur à l'image passée en paramètres
/// </summary>
/// <param name="img">Image</param>
/// <returns>Image modifiée</returns>
public static MyImage SuperpositionOperation(MyImage img) public static MyImage SuperpositionOperation(MyImage img)
{ {
string path = ""; string path = "";
...@@ -260,6 +292,11 @@ namespace S04_Projet ...@@ -260,6 +292,11 @@ namespace S04_Projet
return img.Superposition(secondImg, x, y); return img.Superposition(secondImg, x, y);
} }
/// <summary>
/// Applique un filtre de convolution choisi par l'utilisateur sur l'image
/// </summary>
/// <param name="img">Image</param>
/// <returns>Image modifiée</returns>
public static MyImage FilterOperation(MyImage img) public static MyImage FilterOperation(MyImage img)
{ {
int choix; int choix;
...@@ -273,6 +310,55 @@ namespace S04_Projet ...@@ -273,6 +310,55 @@ namespace S04_Projet
return newImage; return newImage;
} }
/// <summary>
/// Ajoute ou extrait un message caché dans l'image
/// </summary>
/// <param name="img">Image</param>
/// <returns>Image modifiée</returns>
public static MyImage SteganographyOperation(MyImage img)
{
int choix;
MyImage newImage;
string message;
Console.Clear();
Console.WriteLine("Quelle opération souhaitez-vous utiliser ?");
choix = steganoMenu.ShowMenu(0, 3);
Console.Clear();
if (choix == 0)
{
Console.WriteLine("Saisissez le message que vous souhaitez cacher dans l'image :");
message = Console.ReadLine();
sw.Restart();
newImage = img.Steganography(message);
}
else
{
message = img.Steganography();
if (message == "")
{
Console.WriteLine("Aucun message n'a été caché dans cette image");
}
else
{
Console.WriteLine("Le message caché dans l'image est :");
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine(message);
Console.ForegroundColor = ConsoleColor.White;
}
Console.WriteLine("Appuyez sur Entrée pour continuer");
Console.ReadLine();
newImage = img;
}
return newImage;
}
/// <summary>
/// Génère les histogrammes de l'image et les sauvegarde dans un emplacement spécifié par l'utilisateur
/// </summary>
/// <param name="img">Image</param>
/// <returns>Image modifiée</returns>
public static MyImage HistogramOperation(MyImage img) public static MyImage HistogramOperation(MyImage img)
{ {
int width = 0; int width = 0;
...@@ -303,6 +389,11 @@ namespace S04_Projet ...@@ -303,6 +389,11 @@ namespace S04_Projet
return img; return img;
} }
/// <summary>
/// Active ou désactive le mode debug
/// </summary>
/// <param name="img">Image</param>
/// <returns>Même image</returns>
public static MyImage DebugOperation(MyImage img) public static MyImage DebugOperation(MyImage img)
{ {
sw.Restart(); sw.Restart();
...@@ -319,6 +410,11 @@ namespace S04_Projet ...@@ -319,6 +410,11 @@ namespace S04_Projet
return img; return img;
} }
/// <summary>
/// Active ou désative le mode multithreading
/// </summary>
/// <param name="img">Image</param>
/// <returns>Même image</returns>
public static MyImage MultithreadingOperation(MyImage img) public static MyImage MultithreadingOperation(MyImage img)
{ {
if(Program.MULTITHREADING) if(Program.MULTITHREADING)
...@@ -334,6 +430,11 @@ namespace S04_Projet ...@@ -334,6 +430,11 @@ namespace S04_Projet
return img; return img;
} }
/// <summary>
/// Sauvegarde l'image passée en paramètres
/// </summary>
/// <param name="img">Image</param>
/// <returns>null</returns>
public static MyImage SaveOperation(MyImage img) public static MyImage SaveOperation(MyImage img)
{ {
string path = ""; string path = "";
...@@ -346,8 +447,10 @@ namespace S04_Projet ...@@ -346,8 +447,10 @@ namespace S04_Projet
return null; return null;
} }
#endregion /// <summary>
/// Créer une image à partir de rien
/// </summary>
/// <returns>Image créée</returns>
public unsafe static MyImage CreateImageOperation() public unsafe static MyImage CreateImageOperation()
{ {
Options opt = new Options Options opt = new Options
...@@ -435,7 +538,12 @@ namespace S04_Projet ...@@ -435,7 +538,12 @@ namespace S04_Projet
return new MyImage(opt, pixels, pixels, pixels); return new MyImage(opt, pixels, pixels, pixels);
} }
#endregion
/// <summary>
/// Affiche un message d'erreur en rouge
/// </summary>
/// <param name="msg">Message à afficher</param>
public static void AlertMessage(string msg) public static void AlertMessage(string msg)
{ {
Console.ForegroundColor = ConsoleColor.Red; Console.ForegroundColor = ConsoleColor.Red;
...@@ -443,6 +551,14 @@ namespace S04_Projet ...@@ -443,6 +551,14 @@ namespace S04_Projet
Console.ForegroundColor = ConsoleColor.White; Console.ForegroundColor = ConsoleColor.White;
} }
/// <summary>
/// Demande à l'utilisateur de saisir un entier. Tant que la valeur saisie n'est pas valide,
/// affiche un message d'erreur et demande de saisir à nouveau une valeur.
/// </summary>
/// <param name="msg">Message demandant la saisie de l'entier</param>
/// <param name="error">Mettre à true</param>
/// <param name="errorMsg">Mesage en cas de saisie invalide</param>
/// <returns>Entier</returns>
public static int AskForInteger(string msg, bool error, string errorMsg) public static int AskForInteger(string msg, bool error, string errorMsg)
{ {
int result = 0; int result = 0;
......
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace S04_Projet namespace S04_Projet
{ {
......
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace S04_Projet namespace S04_Projet
{ {
class Menu public class Menu
{ {
private string[] menuItems; private string[] menuItems;
/// <summary>
/// Constructeur
/// </summary>
/// <param name="menuItems">Liste des noms des éléments du menu</param>
public Menu(string[] menuItems) public Menu(string[] menuItems)
{ {
this.menuItems = menuItems; this.menuItems = menuItems;
} }
/// <summary>
/// Affiche le menu en partant des points donnés
/// </summary>
/// <param name="xOffset">Coordonée x de départ du menu</param>
/// <param name="yOffset">Coordonée y de départ du menu</param>
/// <returns>Choix fait par l'utilisateur</returns>
public int ShowMenu(int xOffset, int yOffset) public int ShowMenu(int xOffset, int yOffset)
{ {
int choosenItem = 0; int choosenItem = 0;
......
...@@ -3,9 +3,12 @@ using System.Threading; ...@@ -3,9 +3,12 @@ using System.Threading;
namespace S04_Projet namespace S04_Projet
{ {
unsafe class MultiThreadedTask public unsafe class MultiThreadedTask
{ {
#region Attributs #region Attributs
/// <summary>
/// Types d'opérations possibles
/// </summary>
public enum Operation public enum Operation
{ {
Load, Load,
...@@ -37,16 +40,17 @@ namespace S04_Projet ...@@ -37,16 +40,17 @@ namespace S04_Projet
public void SetFile(byte[] file) => this.file = file; public void SetFile(byte[] file) => this.file = file;
#region Constructeurs
/// <summary> /// <summary>
/// Constructeur pour l'opération Filter /// Constructeur pour l'opération Filter
/// </summary> /// </summary>
/// <param name="ToDo"></param> /// <param name="ToDo">Opération à effecuer. Ce constructeur n'est valable que pour les filtres</param>
/// <param name="rPixelPtr"></param> /// <param name="rPixelPtr">Pointeur vers le tableau de pixel rouge</param>
/// <param name="gPixelPtr"></param> /// <param name="gPixelPtr">Pointeur vers le tableau de pixel vert</param>
/// <param name="bPixelPtr"></param> /// <param name="bPixelPtr">Pointeur vers le tableau de pixel bleu</param>
/// <param name="opt"></param> /// <param name="opt">Options de l'image</param>
/// <param name="filter"></param> /// <param name="filter">Filtre à appliquer</param>
/// <param name="factor"></param> /// <param name="factor">Facteur du filtre</param>
public unsafe MultiThreadedTask(Operation ToDo, byte* rPixelPtr, byte* gPixelPtr, byte* bPixelPtr, Options opt, short[,] filter, double factor) public unsafe MultiThreadedTask(Operation ToDo, byte* rPixelPtr, byte* gPixelPtr, byte* bPixelPtr, Options opt, short[,] filter, double factor)
{ {
if (ToDo == Operation.Filter) if (ToDo == Operation.Filter)
...@@ -71,12 +75,12 @@ namespace S04_Projet ...@@ -71,12 +75,12 @@ namespace S04_Projet
/// <summary> /// <summary>
/// Constructeur pour l'opération Load /// Constructeur pour l'opération Load
/// </summary> /// </summary>
/// <param name="ToDo"></param> /// <param name="ToDo">Opération à effecuter. Ce constructeur fonctionne uniquement pour le chargement et la sauvegarde</param>
/// <param name="opt"></param> /// <param name="opt">Options de l'image</param>
/// <param name="rPixelPtr"></param> /// <param name="rPixelPtr">Pointeur vers le tableau de pixel rouge</param>
/// <param name="gPixelPtr"></param> /// <param name="gPixelPtr">Pointeur vers le tableau de pixel vert</param>
/// <param name="bPixelPtr"></param> /// <param name="bPixelPtr">Pointeur vers le tableau de pixel bleu</param>
/// <param name="filePtr"></param> /// <param name="filePtr">Pointeur vers le fichier de sortie</param>
public unsafe MultiThreadedTask(Operation ToDo, Options opt, byte* rPixelPtr, byte* gPixelPtr, byte* bPixelPtr, byte* filePtr) public unsafe MultiThreadedTask(Operation ToDo, Options opt, byte* rPixelPtr, byte* gPixelPtr, byte* bPixelPtr, byte* filePtr)
{ {
if (ToDo == Operation.Load || ToDo == Operation.Save) if (ToDo == Operation.Load || ToDo == Operation.Save)
...@@ -92,8 +96,12 @@ namespace S04_Projet ...@@ -92,8 +96,12 @@ namespace S04_Projet
} }
else throw new Exception("Impossible d'utiliser ce constructeur pour ce type d'opération"); else throw new Exception("Impossible d'utiliser ce constructeur pour ce type d'opération");
} }
#endregion
#region Load #region Load
/// <summary>
/// Initialise le chargement de l'image sur plusieurs threads
/// </summary>
public unsafe void LoadImage() public unsafe void LoadImage()
{ {
Thread[] threads = new Thread[nbProcessors]; Thread[] threads = new Thread[nbProcessors];
...@@ -108,6 +116,10 @@ namespace S04_Projet ...@@ -108,6 +116,10 @@ namespace S04_Projet
threads[i].Join(); threads[i].Join();
} }
/// <summary>
/// Opération éxécutée en parallèle sur plusieurs threads
/// </summary>
/// <param name="i"></param>
private unsafe void LoadImageTask(object i) private unsafe void LoadImageTask(object i)
{ {
int start = nbPixel / nbProcessors * (int)i; int start = nbPixel / nbProcessors * (int)i;
...@@ -128,6 +140,10 @@ namespace S04_Projet ...@@ -128,6 +140,10 @@ namespace S04_Projet
#endregion #endregion
#region Filter #region Filter
/// <summary>
/// Applique un filtre sur une image en utilisant plusieurs threads
/// </summary>
/// <returns>Image modifiée</returns>
public MyImage ApplyFilter() public MyImage ApplyFilter()
{ {
int nbPixel = opt.width * opt.height; int nbPixel = opt.width * opt.height;
...@@ -154,6 +170,10 @@ namespace S04_Projet ...@@ -154,6 +170,10 @@ namespace S04_Projet
return new MyImage(opt, NewRMatrix, NewGMatrix, NewBMatrix); return new MyImage(opt, NewRMatrix, NewGMatrix, NewBMatrix);
} }
/// <summary>
/// Opération éxécutée en parallèle sur plusieurs threads
/// </summary>
/// <param name="i"></param>
private unsafe void ApplyFilterTask(object i) private unsafe void ApplyFilterTask(object i)
{ {
int x, y; int x, y;
...@@ -242,6 +262,9 @@ namespace S04_Projet ...@@ -242,6 +262,9 @@ namespace S04_Projet
#endregion #endregion
#region Save #region Save
/// <summary>
/// Sauvegarde un image en utilisant plusieurs threads
/// </summary>
public unsafe void SaveImage() public unsafe void SaveImage()
{ {
Thread[] threads = new Thread[nbProcessors]; Thread[] threads = new Thread[nbProcessors];
...@@ -256,6 +279,10 @@ namespace S04_Projet ...@@ -256,6 +279,10 @@ namespace S04_Projet
threads[i].Join(); threads[i].Join();
} }
/// <summary>
/// Opération éxécutée en parallèle sur plusieurs threads
/// </summary>
/// <param name="i"></param>
private unsafe void SaveImageTask(object i) private unsafe void SaveImageTask(object i)
{ {
int start = nbPixel / nbProcessors * (int)i; int start = nbPixel / nbProcessors * (int)i;
......
...@@ -12,13 +12,18 @@ namespace S04_Projet ...@@ -12,13 +12,18 @@ namespace S04_Projet
byte[] file; byte[] file;
private int nbProcessors; private int nbProcessors;
/// <summary>
/// Types de filtres de gris disponibles
/// </summary>
public enum GrayFilterType public enum GrayFilterType
{ {
LINEAR, LINEAR,
LUMINOSITY LUMINOSITY
} }
/// <summary>
/// Couleurs rouge, vert, bleu
/// </summary>
public enum RGB public enum RGB
{ {
R, R,
...@@ -563,6 +568,14 @@ namespace S04_Projet ...@@ -563,6 +568,14 @@ namespace S04_Projet
return Images; return Images;
} }
/// <summary>
/// Superpose l'image passée en paramètre à l'image actuelle.
/// Si l'image passée en paramètre dépasse, elle sera coupée
/// </summary>
/// <param name="img">Image à superposer</param>
/// <param name="x">Coordonée x de départ</param>
/// <param name="y">Coordonée y de départ</param>
/// <returns>Nouvelle image</returns>
public unsafe MyImage Superposition(MyImage img, int x, int y) public unsafe MyImage Superposition(MyImage img, int x, int y)
{ {
byte[] newRPixel = rPixels; byte[] newRPixel = rPixels;
...@@ -594,6 +607,12 @@ namespace S04_Projet ...@@ -594,6 +607,12 @@ namespace S04_Projet
return new MyImage(opt, newRPixel, newGPixel, newBPixel); return new MyImage(opt, newRPixel, newGPixel, newBPixel);
} }
/// <summary>
/// Applique le traitement Floyd-Steinberg dithering :
/// https://www.visgraf.impa.br/Courses/ip00/proj/Dithering1/floyd_steinberg_dithering.html
/// </summary>
/// <param name="factor"></param>
/// <returns></returns>
public unsafe MyImage Dithering(byte factor) public unsafe MyImage Dithering(byte factor)
{ {
// cf https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering // cf https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering
...@@ -652,11 +671,21 @@ namespace S04_Projet ...@@ -652,11 +671,21 @@ namespace S04_Projet
return new MyImage(opt, newRPixel, newGPixel, newBPixel); return new MyImage(opt, newRPixel, newGPixel, newBPixel);
} }
/// <summary>
/// Génère une image avec le message passé en paramètre
/// </summary>
/// <param name="sentence">Message caché</param>
/// <returns>Image avec le message caché</returns>
public unsafe MyImage Steganography(string sentence) public unsafe MyImage Steganography(string sentence)
{ {
Options options = opt.Copy(); Options options = opt.Copy();
int size = opt.height * opt.width; int size = opt.height * opt.width;
byte _temp; byte _temp;
int index;
byte goal;
sentence = (char)0x02 + sentence;
sentence += (char)0x03;
byte[] newRPixel = new byte[size]; byte[] newRPixel = new byte[size];
byte[] newGPixel = new byte[size]; byte[] newGPixel = new byte[size];
...@@ -670,15 +699,116 @@ namespace S04_Projet ...@@ -670,15 +699,116 @@ namespace S04_Projet
_temp = (byte)sentence[i]; _temp = (byte)sentence[i];
for (int j = 0; j < 8; j++) for (int j = 0; j < 8; j++)
{ {
goal = (byte)((_temp >> (7 - j)) & 1);
index = i * 8 + j;
if (index % 3 == 0)
{
*(newBPixePtr + index / 3) = PlusorMinus(goal, *(bPtr + index / 3));
}
else if (index % 3 == 1)
{
*(newGPixePtr + index / 3) = PlusorMinus(goal, *(gPtr + index / 3));
}
else
{
*(newRPixePtr + index / 3) = PlusorMinus(goal, *(rPtr + index / 3));
}
}
}
if ((sentence.Length * 8) % 3 == 0)
{
*(newBPixePtr + (sentence.Length * 8) / 3) = *(bPtr + (sentence.Length * 8) / 3);
*(newGPixePtr + (sentence.Length * 8) / 3) = *(gPtr + (sentence.Length * 8) / 3);
*(newRPixePtr + (sentence.Length * 8) / 3) = *(rPtr + (sentence.Length * 8) / 3);
}
else if ((sentence.Length * 8) % 3 == 1)
{
*(newGPixePtr + (sentence.Length * 8) / 3) = *(gPtr + (sentence.Length * 8) / 3);
*(newRPixePtr + (sentence.Length * 8) / 3) = *(rPtr + (sentence.Length * 8) / 3);
}
else if ((sentence.Length * 8) % 3 == 2)
{
*(newRPixePtr + (sentence.Length * 8) / 3) = *(rPtr + (sentence.Length * 8) / 3);
}
for (int i = (sentence.Length * 8 / 3) + 1; i < size; i++)
{
*(newBPixePtr + i) = *(bPtr + i);
*(newGPixePtr + i) = *(gPtr + i);
*(newRPixePtr + i) = *(rPtr + i);
}
}
}
return new MyImage(options, newRPixel, newGPixel, newBPixel);
}
/// <summary>
/// Retourne la chaine de charactère cachée dans l'image s'il y en a une
/// </summary>
/// <returns>vide si pas de message caché. Le message sinon</returns>
public unsafe string Steganography()
{
string message = "";
bool end = false;
int i = 0;
int index;
byte character;
fixed (byte* rPtr = rPixels, gPtr = gPixels, bPtr = bPixels)
{
while(!end)
{
character = 0;
for (int j = 0; j < 8; j++)
{
index = i * 8 + j;
if (index % 3 == 0)
{
character |= (byte)((*(bPtr + index / 3) % 2) << (7-j));
}
else if (index % 3 == 1)
{
character |= (byte)((*(gPtr + index / 3) % 2) << (7 - j));
}
else
{
character |= (byte)((*(rPtr + index / 3) % 2) << (7 - j));
} }
Console.Write(" ");
} }
if (i == 0) {
if(character != 0x02) end = true;
} }
else if (character == 0x03) end = true;
else message += (char)character;
i++;
} }
return null;
} }
return message;
}
/// <summary>
/// Fais en sorte que la valeur ait la même parité que goal
/// </summary>
/// <param name="goal">But</param>
/// <param name="val">Valeur</param>
/// <returns>Valeur de même parité que goal</returns>
private byte PlusorMinus(int goal, byte val)
{
if (val % 2 != goal)
{
if (val == 255) val--;
else val++;
}
return val;
}
/// <summary>
/// Convertit un int en byte
/// </summary>
/// <param name="i">Entier à convertir</param>
/// <returns>Byte</returns>
private byte ToByte(int i) private byte ToByte(int i)
{ {
if (i > 255) return 255; if (i > 255) return 255;
...@@ -757,6 +887,11 @@ namespace S04_Projet ...@@ -757,6 +887,11 @@ namespace S04_Projet
return total; return total;
} }
/// <summary>
/// Retourne la plus grande valeur entre le rouge, vert et bleu à un index donné
/// </summary>
/// <param name="i">Index</param>
/// <returns>Valeur max</returns>
private unsafe byte MaxRGB(int i) private unsafe byte MaxRGB(int i)
{ {
fixed (byte* rPtr = rPixels, gPtr = gPixels, bPtr = bPixels) fixed (byte* rPtr = rPixels, gPtr = gPixels, bPtr = bPixels)
...@@ -767,6 +902,11 @@ namespace S04_Projet ...@@ -767,6 +902,11 @@ namespace S04_Projet
} }
} }
/// <summary>
/// Retourne la plus petite valeur entre le rouge, vert et bleu à un index donnée
/// </summary>
/// <param name="i">Index</param>
/// <returns>Valeur min</returns>
private unsafe byte MinRGB(int i) private unsafe byte MinRGB(int i)
{ {
fixed (byte* rPtr = rPixels, gPtr = gPixels, bPtr = bPixels) fixed (byte* rPtr = rPixels, gPtr = gPixels, bPtr = bPixels)
...@@ -777,6 +917,12 @@ namespace S04_Projet ...@@ -777,6 +917,12 @@ namespace S04_Projet
} }
} }
/// <summary>
/// Retourne la valeur maximale d'un tableau d'entier
/// </summary>
/// <param name="tab">Pointeur vers le tableau</param>
/// <param name="length">Taille du tableau</param>
/// <returns>Valeur max</returns>
private unsafe int Max(int* tab, int length) private unsafe int Max(int* tab, int length)
{ {
int max = 0; int max = 0;
......
...@@ -4,7 +4,7 @@ using System.IO; ...@@ -4,7 +4,7 @@ using System.IO;
namespace S04_Projet namespace S04_Projet
{ {
class Program public class Program
{ {
public static bool MULTITHREADING = false; public static bool MULTITHREADING = false;
public static int MAX_THREADS = Environment.ProcessorCount; public static int MAX_THREADS = Environment.ProcessorCount;
...@@ -19,10 +19,6 @@ namespace S04_Projet ...@@ -19,10 +19,6 @@ namespace S04_Projet
static void Main(string[] args) static void Main(string[] args)
{ {
MyImage img = new MyImage("img/coco.bmp");
img.Steganography("message");
Console.Read();
/*
#region Arguments #region Arguments
if (args.Length > 0) if (args.Length > 0)
{ {
...@@ -65,9 +61,14 @@ namespace S04_Projet ...@@ -65,9 +61,14 @@ namespace S04_Projet
Console.WriteLine("Image sauvegardée en {0}ms!", Display.elapsedTime); Console.WriteLine("Image sauvegardée en {0}ms!", Display.elapsedTime);
Console.Read(); Console.Read();
} }
#endregion */ #endregion
} }
/// <summary>
/// Interprète les arguements passés au programme s'il y en a
/// </summary>
/// <param name="args"></param>
/// <param name="i"></param>
private static void Arguments(string[] args, int i) private static void Arguments(string[] args, int i)
{ {
int increment = 1; int increment = 1;
......
using Microsoft.VisualStudio.TestTools.UnitTesting;
using S04_Projet;
namespace Tests
{
[TestClass]
public class FilterTest
{
[TestMethod]
public void contrastPlus()
{
short[,] contrastPlus = new short[,]
{
{ 0,-1, 0 },
{-1, 5,-1 },
{ 0,-1, 0 }
};
CollectionAssert.AreEqual(contrastPlus, Filter.Filtres[0]);
}
[TestMethod]
public void flou()
{
short[,] flou = new short[,]
{
{ 1, 1, 1 },
{ 1, 1, 1 },
{ 1, 1, 1 }
};
CollectionAssert.AreEqual(flou, Filter.Filtres[1]);
}
[TestMethod]
public void renforcement()
{
short[,] renforcement = new short[,]
{
{ 0, 0, 0 },
{-1, 1, 0 },
{ 0, 0, 0 }
};
CollectionAssert.AreEqual(renforcement, Filter.Filtres[2]);
}
[TestMethod]
public void detection()
{
short[,] detection = new short[,]
{
{ 0, 1, 0 },
{ 1,-4, 1 },
{ 0, 1, 0 }
};
CollectionAssert.AreEqual(detection, Filter.Filtres[3]);
}
[TestMethod]
public void repoussage()
{
short[,] repoussage = new short[,]
{
{-2,-1, 0 },
{-1, 1, 1 },
{ 0, 1, 2 }
};
CollectionAssert.AreEqual(repoussage, Filter.Filtres[4]);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.props" Condition="Exists('..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{55E3E9D6-F5C5-47AD-851C-EE55CCE639F6}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Tests</RootNamespace>
<AssemblyName>Tests</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\MSTest.TestFramework.1.2.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\MSTest.TestFramework.1.2.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="FilterTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\S04_Projet\ImageProcessing.csproj">
<Project>{229d3602-654b-498b-9478-5cc3982c358c}</Project>
<Name>ImageProcessing</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>Ce projet fait référence à des packages NuGet qui sont manquants sur cet ordinateur. Utilisez l'option de restauration des packages NuGet pour les télécharger. Pour plus d'informations, consultez http://go.microsoft.com/fwlink/?LinkID=322105. Le fichier manquant est : {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.props'))" />
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.targets'))" />
</Target>
<Import Project="..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.targets" Condition="Exists('..\packages\MSTest.TestAdapter.1.2.1\build\net45\MSTest.TestAdapter.targets')" />
</Project>
\ No newline at end of file
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Tests")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("55e3e9d6-f5c5-47ad-851c-ee55cce639f6")]
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MSTest.TestAdapter" version="1.2.1" targetFramework="net461" />
<package id="MSTest.TestFramework" version="1.2.1" targetFramework="net461" />
</packages>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment