Fonctions trait(), retourner(), convRVB(), cercle(), disque(), redimensionner

Les fonctions sont accessibles en mode testing mais leur commande n'est pas intégrée.
* Traitement d'image
	* Ajout de la fonction trait() (algorithme original), de retourner() et de convRVB()
	* Correction des fonctions cercle(), disque() et redimensionner()
* Utilitaires
	* Ajout d'un fichier de log (PILG-log.txt), pour éviter de surcharger la console, et fonctionner même en mode RELEASE
	* Déplacement de afficherImage() depuis analyserCommande.cpp
	* Ajout d'une constante ECHELLE à afficherImage() pour zoomer l'affichage
* Objet Image
	* Correction d'une inversion X/Y visible sur des images plus hautes que large
* Mise à jour de TODO.md
* Modification des règles de formattage (encore des lignes pour rien)
This commit is contained in:
Geoffrey Frogeye 2014-05-20 20:00:32 +02:00
parent 077ef18a41
commit a618bdaf42
10 changed files with 456 additions and 203 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
*.sublime-* *.sublime-*
PILG-log.txt

28
TODO.md
View file

@ -18,10 +18,10 @@
* Pixel **C** * Pixel **C**
* Image **C** * Image **C**
* Fonctions **D** * Fonctions **D**
* Gestion de fichier **D** * Gestion de fichier **A**
* Créer **C** * Créer **C**
* Ouvrir **D** * Ouvrir **C**
* Enregistrer **D** * Enregistrer **C**
* Importer **A** * Importer **A**
* Édition * Édition
* Copier tout * Copier tout
@ -30,24 +30,24 @@
* Annuler * Annuler
* Refaire * Refaire
* Couleur **D** * Couleur **D**
* Teinte **A** * Teinte **D**
* Saturation **D** * Saturation **D**
* Luminosité **A** * Luminosité **D**
* Contraste **A** * Contraste
* Dessin **D** * Dessin **C**
* Trait **A** * Trait **C**
* Rectangle **C** * Rectangle **C**
* Cercle **A** * Cercle **C**
* Disque **A** * Disque **C**
* Géométrie **D** * Géométrie **D**
* Zoomer * Zoomer
* Pivoter **C** * Pivoter **C**
* Retourner **D** * Retourner **C**
* Redimensionner **A** * Redimensionner **C**
* Conversion du mode **D** * Conversion du mode **C**
* Binaire **C** * Binaire **C**
* Niveaux de gris **C** * Niveaux de gris **C**
* Couleur **D** * Couleur **C**
* Aide * Aide
* Documentation * Documentation

View file

@ -11,13 +11,16 @@ SDL_Surface *fenetreImage;
void definirPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) { void definirPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) {
int nbOctetsParPixel = surface->format->BytesPerPixel; int nbOctetsParPixel = surface->format->BytesPerPixel;
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * nbOctetsParPixel; Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * nbOctetsParPixel;
switch (nbOctetsParPixel) { switch (nbOctetsParPixel) {
case 1: case 1:
*p = pixel; *p = pixel;
break; break;
case 2: case 2:
*(Uint16 *)p = pixel; *(Uint16 *)p = pixel;
break; break;
case 3: case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff; p[0] = (pixel >> 16) & 0xff;
@ -28,7 +31,9 @@ void definirPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) {
p[1] = (pixel >> 8) & 0xff; p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff; p[2] = (pixel >> 16) & 0xff;
} }
break; break;
case 4: case 4:
*(Uint32 *)p = pixel; *(Uint32 *)p = pixel;
break; break;
@ -41,18 +46,14 @@ void setNomFenetre(std::string nom) { // Change le nom de la fenêtre
void pointFenetre(int x, int y, int r, int v, int b) { void pointFenetre(int x, int y, int r, int v, int b) {
// std::cout << "(" << x << ";" << y << ") = (" << r << ";" << v << ";" << b << ")" << std::endl; // DEBUG // std::cout << "(" << x << ";" << y << ") = (" << r << ";" << v << ";" << b << ")" << std::endl; // DEBUG
Uint32 pixel; Uint32 pixel;
Uint8 u_r, u_v, u_b, u_a; Uint8 u_r, u_v, u_b, u_a;
u_r = (r > 255 ? 0xff : (Uint8) r); u_r = (r > 255 ? 0xff : (Uint8) r);
u_v = (v > 255 ? 0xff : (Uint8) v); u_v = (v > 255 ? 0xff : (Uint8) v);
u_b = (b > 255 ? 0xff : (Uint8) b); u_b = (b > 255 ? 0xff : (Uint8) b);
u_a = 0xff; u_a = 0xff;
pixel = SDL_MapRGBA(fenetreImage->format, u_r, u_v, u_b, u_a); pixel = SDL_MapRGBA(fenetreImage->format, u_r, u_v, u_b, u_a);
definirPixel(fenetreImage, x, y, pixel); definirPixel(fenetreImage, x, y, pixel);
} }
void afficherFenetre() { void afficherFenetre() {
@ -70,7 +71,8 @@ void attendreFenetre() {
do { do {
SDL_WaitEvent(&evenement); SDL_WaitEvent(&evenement);
} while (evenement.type != SDL_QUIT && evenement.type != SDL_KEYDOWN); //|| evenement.type != SDL_KEYDOWN); } while (evenement.type != SDL_QUIT &&
evenement.type != SDL_KEYDOWN); //|| evenement.type != SDL_KEYDOWN);
} }
void fermerFenetre() { void fermerFenetre() {
@ -81,12 +83,15 @@ void fermerFenetre() {
} }
void ouvrirFenetre(int dimensionX, int dimensionY, std::string nom) { // Crée une fenêtre void ouvrirFenetre(int dimensionX, int dimensionY,
std::string nom) { // Crée une fenêtre
SDL_Init(SDL_INIT_VIDEO); SDL_Init(SDL_INIT_VIDEO);
fenetreDimensionX = dimensionX; fenetreDimensionX = dimensionX;
fenetreDimensionY = dimensionY; fenetreDimensionY = dimensionY;
fenetreEcran = SDL_SetVideoMode(fenetreDimensionX, fenetreDimensionY, 32, SDL_HWSURFACE); fenetreEcran = SDL_SetVideoMode(fenetreDimensionX, fenetreDimensionY, 32,
fenetreImage = SDL_CreateRGBSurface(SDL_HWSURFACE, fenetreDimensionX, fenetreDimensionY, 32, 0, 0, 0, 0); SDL_HWSURFACE);
fenetreImage = SDL_CreateRGBSurface(SDL_HWSURFACE, fenetreDimensionX,
fenetreDimensionY, 32, 0, 0, 0, 0);
SDL_FillRect(fenetreImage, NULL, SDL_MapRGB(fenetreEcran->format, 0, 0, 0)); SDL_FillRect(fenetreImage, NULL, SDL_MapRGB(fenetreEcran->format, 0, 0, 0));
setNomFenetre(nom); setNomFenetre(nom);
SDL_LockSurface(fenetreImage); SDL_LockSurface(fenetreImage);

View file

@ -2,45 +2,6 @@
#include <string> #include <string>
#include <iostream> #include <iostream>
void afficherImage(Image image) {
int x, y, r, v, b, dimensionX = image.g_dimensionX(), dimensionY = image.g_dimensionY(), typeComposantes = image.g_typeComposantes();
float ratio = (255.0 / image.g_maxComposante());
Pixel pixel;
if (fenetreOuverte && (dimensionX != fenetreDimensionX || dimensionY != fenetreDimensionY)) {
fermerFenetre();
}
ouvrirFenetre(dimensionX, dimensionY, "PILG");
for (x = 0; x < dimensionX; x++) {
for (y = 0; y < dimensionY; y++) {
image.g_pixel(x, y, pixel);
switch (typeComposantes) {
case PILG_BIN:
r = v = b = (pixel.n ? 255 : 0);
break;
case PILG_NIV:
r = v = b = pixel.g * ratio;
break;
case PILG_RVB:
r = pixel.r * ratio;
v = pixel.v * ratio;
b = pixel.b * ratio;
break;
}
pointFenetre(x, y, r, v, b);
}
}
afficherFenetre();
}
void messageErreur(string message) {
cerr << "Erreur : " << message << '.' << endl;
}
void decoupeCommande(string commande, vector< string > &decoupe) { void decoupeCommande(string commande, vector< string > &decoupe) {
// Boucle de découpage // Boucle de découpage
// vector< string > decoupe; // vector< string > decoupe;
@ -50,13 +11,17 @@ void decoupeCommande(string commande, vector< string > &decoupe) {
bool vaEchapper = false; bool vaEchapper = false;
bool entreSimplesGuillemets = false; bool entreSimplesGuillemets = false;
bool entreDoublesGuillemets = false; bool entreDoublesGuillemets = false;
for (int i = 0; i < commande.length(); i++) { for (int i = 0; i < commande.length(); i++) {
echape = false; echape = false;
if (vaEchapper) { if (vaEchapper) {
vaEchapper = false; vaEchapper = false;
echape = true; echape = true;
} }
if (commande[i] == ' ' && !(echape || entreSimplesGuillemets || entreDoublesGuillemets)) {
if (commande[i] == ' ' && !(echape || entreSimplesGuillemets ||
entreDoublesGuillemets)) {
// cout << i << " : " << "espace" << endl; // cout << i << " : " << "espace" << endl;
if (!dansLeVide) { if (!dansLeVide) {
// cout << "Ajout de " << elementCourrant << endl; // cout << "Ajout de " << elementCourrant << endl;
@ -92,6 +57,7 @@ void decoupeCommande(string commande, vector< string > &decoupe) {
dansLeVide = false; dansLeVide = false;
} }
} }
if (!dansLeVide) { if (!dansLeVide) {
// cout << "Ajout de " << elementCourrant << endl; // cout << "Ajout de " << elementCourrant << endl;
decoupe.push_back(elementCourrant); decoupe.push_back(elementCourrant);
@ -100,47 +66,52 @@ void decoupeCommande(string commande, vector< string > &decoupe) {
typedef struct Commande { typedef struct Commande {
string fonction; string fonction;
int x1, x2, y1, y2; int x1, x2, y1, y2;
float angle; float angle;
string fichierEntree, fichierSortie; string fichierEntree, fichierSortie;
Pixel couleur; Pixel couleur;
// ... // ...
vector< string > argumentsPresents; vector< string > argumentsPresents;
} Commande; } Commande;
int analyserDecoupe(Commande &commande, vector< string > decoupe, Image const &image) { int analyserDecoupe(Commande &commande, vector< string > decoupe,
Image const &image) {
// for (int i = 0; i < decoupe.size(); i++) { // DEBUG // for (int i = 0; i < decoupe.size(); i++) { // DEBUG
// cout << "Argument " << i << " = " << decoupe[i] << endl; // cout << "Argument " << i << " = " << decoupe[i] << endl;
// } // }
commande.couleur = image.g_pixelVide(); commande.couleur = image.g_pixelVide();
commande.fonction = decoupe[0]; commande.fonction = decoupe[0];
// // Analyse des arguments // // Analyse des arguments
for (int i = 1; i < decoupe.size(); i++) { for (int i = 1; i < decoupe.size(); i++) {
if (decoupe[i].at(0) == '-') { if (decoupe[i].at(0) == '-') {
if (decoupe[i] == "-x1" || decoupe[i] == "-x0" || decoupe[i] == "-x") { if (decoupe[i] == "-x1" || decoupe[i] == "-x0" || decoupe[i] == "-x") {
commande.argumentsPresents.push_back("x1"); commande.argumentsPresents.push_back("x1");
i++; i++;
if (chaineVersEntier(decoupe[i], commande.x1)) { if (chaineVersEntier(decoupe[i], commande.x1)) {
return 3; return 3;
} }
} else if (decoupe[i] == "-y1" || decoupe[i] == "-y0" || decoupe[i] == "-y") { } else if (decoupe[i] == "-y1" || decoupe[i] == "-y0" || decoupe[i] == "-y") {
commande.argumentsPresents.push_back("y1"); commande.argumentsPresents.push_back("y1");
i++; i++;
if (chaineVersEntier(decoupe[i], commande.y1)) { if (chaineVersEntier(decoupe[i], commande.y1)) {
return 3; return 3;
} }
} else if (decoupe[i] == "-x2") { } else if (decoupe[i] == "-x2") {
commande.argumentsPresents.push_back("x2"); commande.argumentsPresents.push_back("x2");
i++; i++;
if (chaineVersEntier(decoupe[i], commande.x2)) { if (chaineVersEntier(decoupe[i], commande.x2)) {
return 3; return 3;
} }
} else if (decoupe[i] == "-y2") { } else if (decoupe[i] == "-y2") {
commande.argumentsPresents.push_back("y2"); commande.argumentsPresents.push_back("y2");
i++; i++;
if (chaineVersEntier(decoupe[i], commande.y2)) { if (chaineVersEntier(decoupe[i], commande.y2)) {
return 3; return 3;
} }
@ -148,6 +119,7 @@ int analyserDecoupe(Commande &commande, vector< string > decoupe, Image const &i
commande.argumentsPresents.push_back("couleur"); commande.argumentsPresents.push_back("couleur");
i++; i++;
commande.couleur = image.g_pixelVide(); commande.couleur = image.g_pixelVide();
switch (image.g_typeComposantes()) { switch (image.g_typeComposantes()) {
case PILG_BIN: case PILG_BIN:
if (decoupe[i] == "b" || decoupe[i] == "1") { if (decoupe[i] == "b" || decoupe[i] == "1") {
@ -157,42 +129,55 @@ int analyserDecoupe(Commande &commande, vector< string > decoupe, Image const &i
} else { } else {
return 4; return 4;
} }
break; break;
case PILG_NIV: case PILG_NIV:
int g; int g;
if (!chaineVersEntier(decoupe[i], g)) { if (!chaineVersEntier(decoupe[i], g)) {
return 3; return 3;
} }
if (g > image.g_maxComposante()) { if (g > image.g_maxComposante()) {
return 5; return 5;
} }
commande.couleur.g = g; commande.couleur.g = g;
break; break;
case PILG_RVB: case PILG_RVB:
int composante = 0; int composante = 0;
string chaineCourante = ""; string chaineCourante = "";
int entierCourant = 0; int entierCourant = 0;
for (int iS = 0; iS <= decoupe[i].length(); iS++) { for (int iS = 0; iS <= decoupe[i].length(); iS++) {
if (decoupe[i][iS] == ':' || iS == decoupe[i].length()) { if (decoupe[i][iS] == ':' || iS == decoupe[i].length()) {
if (chaineVersEntier(chaineCourante, entierCourant)) { if (chaineVersEntier(chaineCourante, entierCourant)) {
return 3; return 3;
} }
if (entierCourant > image.g_maxComposante()) { if (entierCourant > image.g_maxComposante()) {
return 5; return 5;
} }
switch (composante) { switch (composante) {
case 0: case 0:
commande.couleur.r = entierCourant; commande.couleur.r = entierCourant;
break; break;
case 1: case 1:
commande.couleur.v = entierCourant; commande.couleur.v = entierCourant;
break; break;
case 2: case 2:
commande.couleur.b = entierCourant; commande.couleur.b = entierCourant;
break; break;
default: default:
return 6; return 6;
} }
chaineCourante = ""; chaineCourante = "";
entierCourant = 0; entierCourant = 0;
composante++; composante++;
@ -200,17 +185,21 @@ int analyserDecoupe(Commande &commande, vector< string > decoupe, Image const &i
chaineCourante += decoupe[i][iS]; chaineCourante += decoupe[i][iS];
} }
} }
if (composante != 3) { if (composante != 3) {
return 6; return 6;
} }
break; break;
} }
if (!image.v_pixel(commande.couleur)) { if (!image.v_pixel(commande.couleur)) {
return 7; return 7;
} }
} else if (decoupe[i] == "-angle" || decoupe[i] == "-a") { } else if (decoupe[i] == "-angle" || decoupe[i] == "-a") {
commande.argumentsPresents.push_back("angle"); commande.argumentsPresents.push_back("angle");
i++; i++;
if (chaineVersFlottant(decoupe[i], commande.angle)) { if (chaineVersFlottant(decoupe[i], commande.angle)) {
return 8; return 8;
} }
@ -222,11 +211,15 @@ int analyserDecoupe(Commande &commande, vector< string > decoupe, Image const &i
return 1; return 1;
} }
} }
// for (int i = 0; i < commande.argumentsPresents.size(); i++) { // DEBUG #if DEBUG
// cout << "Argument présent " << i << " = " << commande.argumentsPresents[i] << endl;
// } for (int i = 0; i < commande.argumentsPresents.size(); i++) {
journal << "\"" << commande.argumentsPresents[i] << "\" ";
}
journal << endl;
#endif
return 0; return 0;
} }
@ -236,6 +229,7 @@ bool argumentPresent(Commande commande, string argumentVoulu) {
return true; return true;
} }
} }
return false; return false;
} }
@ -244,7 +238,8 @@ int executerCommande(Commande commande, Image &image) {
if (argumentPresent(commande, "x1") && argumentPresent(commande, "x2") if (argumentPresent(commande, "x1") && argumentPresent(commande, "x2")
&& argumentPresent(commande, "y1") && argumentPresent(commande, "y2") && argumentPresent(commande, "y1") && argumentPresent(commande, "y2")
&& argumentPresent(commande, "couleur")) { && argumentPresent(commande, "couleur")) {
if (rectangle(image, image, commande.x1, commande.y1, commande.x2, commande.y2, commande.couleur)) { if (rectangle(image, image, commande.x1, commande.y1, commande.x2, commande.y2,
commande.couleur)) {
return 3; return 3;
} }
} else { } else {
@ -267,58 +262,75 @@ int executerCommande(Commande commande, Image &image) {
if (convNIV(image, image)) { if (convNIV(image, image)) {
return 3; return 3;
} }
// } else if (commande.fonction == "convRVB") { // } else if (commande.fonction == "convRVB") {
// convRVB(image, image); // convRVB(image, image);
} else { } else {
return 1; return 1;
} }
return 0; return 0;
} }
void procederCommande(vector< string > decoupe, Image &image) { void procederCommande(vector< string > decoupe, Image &image) {
Commande commande; Commande commande;
switch (analyserDecoupe(commande, decoupe, image)) { switch (analyserDecoupe(commande, decoupe, image)) {
case 0: case 0:
switch (executerCommande(commande, image)) { switch (executerCommande(commande, image)) {
case 0: case 0:
break; break;
case 1: case 1:
messageErreur("Fonction inconnue"); messageErreur("Fonction inconnue");
break; break;
case 2: case 2:
messageErreur("Arguments manquants"); messageErreur("Arguments manquants");
break; break;
case 3: case 3:
messageErreur("Erreur dans l'execution de la commande"); messageErreur("Erreur dans l'execution de la commande");
break; break;
default: default:
messageErreur("Impossible d'éxecuter la fonction"); messageErreur("Impossible d'éxecuter la fonction");
} }
break; break;
case 1: case 1:
messageErreur("Un argument a été attendu et autre chose a été donné"); messageErreur("Un argument a été attendu et autre chose a été donné");
break; break;
case 2: case 2:
messageErreur("Argument inconnu"); messageErreur("Argument inconnu");
break; break;
case 3: case 3:
messageErreur("Un entier a été attendu et n'a pas été donné"); messageErreur("Un entier a été attendu et n'a pas été donné");
break; break;
case 4: case 4:
messageErreur("La couleur d'une image binaire doit être blanc (1) ou noir (0)"); messageErreur("La couleur d'une image binaire doit être blanc (1) ou noir (0)");
break; break;
case 5: case 5:
messageErreur("La valeur d'une composante de couleur donnée est superieure au maximum de composante de l'image"); messageErreur("La valeur d'une composante de couleur donnée est superieure au maximum de composante de l'image");
break; break;
case 6: case 6:
messageErreur("La couleur d'une image RVB possède trois composantes"); messageErreur("La couleur d'une image RVB possède trois composantes");
break; break;
case 7: case 7:
messageErreur("La couleur donnée n'est pas valide, la raison en est inconnue"); messageErreur("La couleur donnée n'est pas valide, la raison en est inconnue");
break; break;
case 8: case 8:
messageErreur("Un nombre décimal a été attendu et n'a pas été donné (le programme n'accepte que les points)"); messageErreur("Un nombre décimal a été attendu et n'a pas été donné (le programme n'accepte que les points)");
break; break;
default: default:
messageErreur("Impossible d'analyser la commande"); messageErreur("Impossible d'analyser la commande");
break; break;
@ -328,10 +340,11 @@ void procederCommande(vector< string > decoupe, Image &image) {
void boucleDeCommandes(Image image) { // REPL void boucleDeCommandes(Image image) { // REPL
bool continuer = true; bool continuer = true;
string commandeTexte; string commandeTexte;
while (continuer) { while (continuer) {
cout << "$ "; cout << "$ ";
getline(cin, commandeTexte); getline(cin, commandeTexte);
if (commandeTexte == "quitter" || commandeTexte == "exit") { if (commandeTexte == "quitter" || commandeTexte == "exit") {
continuer = false; continuer = false;
} else { } else {

View file

@ -1,12 +1,17 @@
#include "image.h" #include "image.h"
Image::Image(int dimensionX, int dimensionY, int maxComposante, PILG_Comp typeComposantes): m_dimensionX(dimensionX), m_dimensionY(dimensionY), m_maxComposante(maxComposante), m_typeComposantes(typeComposantes) { Image::Image(int dimensionX, int dimensionY, int maxComposante,
PILG_Comp typeComposantes): m_dimensionX(dimensionX), m_dimensionY(dimensionY),
m_maxComposante(maxComposante), m_typeComposantes(typeComposantes) {
Pixel pixelVide = g_pixelVide(); Pixel pixelVide = g_pixelVide();
for (int xT = 0; xT < dimensionX; xT++) { for (int xT = 0; xT < dimensionX; xT++) {
std::vector< Pixel > colonne; std::vector< Pixel > colonne;
for (int yT = 0; yT < dimensionX; yT++) {
for (int yT = 0; yT < dimensionY; yT++) {
colonne.push_back(pixelVide); colonne.push_back(pixelVide);
} }
m_tab.push_back(colonne); m_tab.push_back(colonne);
} }
} }
@ -53,17 +58,21 @@ Pixel Image::g_pixelVide() const {
Pixel pixel; Pixel pixel;
pixel.typeComposantes = m_typeComposantes; pixel.typeComposantes = m_typeComposantes;
pixel.maxComposante = m_maxComposante; pixel.maxComposante = m_maxComposante;
switch (pixel.typeComposantes) { switch (pixel.typeComposantes) {
case PILG_BIN: case PILG_BIN:
pixel.b = false; pixel.b = false;
break; break;
case PILG_NIV: case PILG_NIV:
pixel.g = 0; pixel.g = 0;
break; break;
case PILG_RVB: case PILG_RVB:
pixel.r = pixel.v = pixel.b = 0; pixel.r = pixel.v = pixel.b = 0;
break; break;
} }
return pixel; return pixel;
} }
@ -73,20 +82,23 @@ Image Image::g_vide() const {
// Validateurs // Validateurs
bool Image::v_pixel(Pixel pixel) const { bool Image::v_pixel(Pixel pixel) const {
if (pixel.typeComposantes == m_typeComposantes if (pixel.typeComposantes == m_typeComposantes
&& pixel.maxComposante == m_maxComposante) { && pixel.maxComposante == m_maxComposante) {
switch (pixel.typeComposantes) { switch (pixel.typeComposantes) {
case PILG_BIN: case PILG_BIN:
return true; return true;
break; break;
case PILG_NIV: case PILG_NIV:
return (pixel.g <= pixel.maxComposante); return (pixel.g <= pixel.maxComposante);
break; break;
case PILG_RVB: case PILG_RVB:
return (pixel.r <= pixel.maxComposante return (pixel.r <= pixel.maxComposante
&& pixel.v <= pixel.maxComposante && pixel.v <= pixel.maxComposante
&& pixel.b <= pixel.maxComposante); && pixel.b <= pixel.maxComposante);
break; break;
default: default:
return false; return false;
break; break;

View file

@ -14,7 +14,8 @@ typedef struct Pixel {
class Image { class Image {
public: public:
Image(int dimensionX, int dimensionY, int maxComposante, PILG_Comp typeComposantes); Image(int dimensionX, int dimensionY, int maxComposante,
PILG_Comp typeComposantes);
// Getters // Getters
int g_dimensionX() const; int g_dimensionX() const;
int g_dimensionY() const; int g_dimensionY() const;

View file

@ -11,25 +11,26 @@ using namespace std;
#define NOMBREOR 1.61803398875 #define NOMBREOR 1.61803398875
int main(int argc, char *args[]) { int main(int argc, char *args[]) {
#if defined(WIN32) // Permet de refaire fonctionner cout et cerr sous Windows après démarrage de SDL #if defined(WIN32) // Permet de refaire fonctionner cout et cerr sous Windows après démarrage de SDL
freopen("CON", "w", stdout); freopen("CON", "w", stdout);
freopen("CON", "w", stderr); freopen("CON", "w", stderr);
#endif #endif
presentation(); presentation();
cout << endl;
Image image = imageDefaut(); Image image = imageDefaut();
if (argc > 1) { // Si la commande a été entrée avec des arguments if (argc > 1) { // Si la commande a été entrée avec des arguments
vector< string > decoupe; vector< string > decoupe;
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
decoupe.push_back(args[i]); decoupe.push_back(args[i]);
} }
procederCommande(decoupe, image); procederCommande(decoupe, image);
} else { } else {
afficherImage(image); afficherImage(image);
boucleDeCommandes(image); boucleDeCommandes(image);
} }
return 0; return 0;
} }

View file

@ -16,60 +16,73 @@ Image genererRoue(int dimX, int dimY, int maxComposante) {
Pixel pointRoue = imageRoue.g_pixelVide(); Pixel pointRoue = imageRoue.g_pixelVide();
int x, y, step; int x, y, step;
float substep, lum; float substep, lum;
for (x = 0; x < dimX; x++) { for (x = 0; x < dimX; x++) {
for (y = 0; y < dimY; y++) { for (y = 0; y < dimY; y++) {
step = (x * 6.0) / dimX; step = (x * 6.0) / dimX;
substep = (x - step * (dimX / 6.0)) / (dimX / 6.0) * maxComposante; substep = (x - step * (dimX / 6.0)) / (dimX / 6.0) * maxComposante;
lum = 1 - ((float) y) / dimY; lum = 1 - ((float) y) / dimY;
switch (step) { switch (step) {
case 0: case 0:
pointRoue.r = maxComposante; pointRoue.r = maxComposante;
pointRoue.v = substep; pointRoue.v = substep;
pointRoue.b = 0; pointRoue.b = 0;
break; break;
case 1: case 1:
pointRoue.r = maxComposante - substep; pointRoue.r = maxComposante - substep;
pointRoue.v = maxComposante; pointRoue.v = maxComposante;
pointRoue.b = 0; pointRoue.b = 0;
break; break;
case 2: case 2:
pointRoue.r = 0; pointRoue.r = 0;
pointRoue.v = maxComposante; pointRoue.v = maxComposante;
pointRoue.b = substep; pointRoue.b = substep;
break; break;
case 3: case 3:
pointRoue.r = 0; pointRoue.r = 0;
pointRoue.v = maxComposante - substep; pointRoue.v = maxComposante - substep;
pointRoue.b = maxComposante; pointRoue.b = maxComposante;
break; break;
case 4: case 4:
pointRoue.r = substep; pointRoue.r = substep;
pointRoue.v = 0; pointRoue.v = 0;
pointRoue.b = maxComposante; pointRoue.b = maxComposante;
break; break;
case 5: case 5:
pointRoue.r = maxComposante; pointRoue.r = maxComposante;
pointRoue.v = 0; pointRoue.v = 0;
pointRoue.b = maxComposante - substep; pointRoue.b = maxComposante - substep;
break; break;
} }
// Dégradé vers le noir // Dégradé vers le noir
pointRoue.r = pointRoue.r * lum; pointRoue.r = pointRoue.r * lum;
pointRoue.v = pointRoue.v * lum; pointRoue.v = pointRoue.v * lum;
pointRoue.b = pointRoue.b * lum; pointRoue.b = pointRoue.b * lum;
// // Remise dans l'intervalle // // Remise dans l'intervalle
// pointRoue.r = (pointRoue.r > maxComposante ? maxComposante : pointRoue.r); // pointRoue.r = (pointRoue.r > maxComposante ? maxComposante : pointRoue.r);
// pointRoue.v = (pointRoue.v > maxComposante ? maxComposante : pointRoue.v); // pointRoue.v = (pointRoue.v > maxComposante ? maxComposante : pointRoue.v);
// pointRoue.b = (pointRoue.b > maxComposante ? maxComposante : pointRoue.b); // pointRoue.b = (pointRoue.b > maxComposante ? maxComposante : pointRoue.b);
if (imageRoue.s_pixel(x, y, pointRoue) == 1) { if (imageRoue.s_pixel(x, y, pointRoue) == 1) {
cerr << "Erreur : s_pixel() a été entré avec des valeurs incorrectes" << endl; journal << "Erreur : s_pixel() a été entré avec des valeurs incorrectes" <<
cout << "X : " << x << " - Y: " << y << " - R : " << pointRoue.r << " - V : " << pointRoue.v << " - B : " << pointRoue.b << endl; // DEBUG endl;
journal << "X : " << x << " - Y: " << y << " - R : " << pointRoue.r << " - V : "
<<
pointRoue.v << " - B : " << pointRoue.b << endl;
} }
imageRoue.g_pixel(x, y, pointRoue); imageRoue.g_pixel(x, y, pointRoue);
} }
} }
return imageRoue; return imageRoue;
} }
@ -77,12 +90,14 @@ Image genererDegrade(int dimX, int dimY, int maxComposante) {
Image image(dimX, dimY, maxComposante, PILG_NIV); Image image(dimX, dimY, maxComposante, PILG_NIV);
Pixel pixel = image.g_pixelVide(); Pixel pixel = image.g_pixelVide();
int x, y; int x, y;
for (x = 0; x < dimX; x++) { for (x = 0; x < dimX; x++) {
for (y = 0; y < dimY; y++) { for (y = 0; y < dimY; y++) {
pixel.g = (float) x * maxComposante / dimX; pixel.g = (float) x * maxComposante / dimX;
image.s_pixel(x, y, pixel); image.s_pixel(x, y, pixel);
} }
} }
return image; return image;
} }
@ -90,59 +105,71 @@ Image genererBruit(int dimX, int dimY) {
Image image(dimX, dimY, 0, PILG_BIN); Image image(dimX, dimY, 0, PILG_BIN);
Pixel pixel = image.g_pixelVide(); Pixel pixel = image.g_pixelVide();
int x, y; int x, y;
for (x = 0; x < dimX; x++) { for (x = 0; x < dimX; x++) {
for (y = 0; y < dimY; y++) { for (y = 0; y < dimY; y++) {
pixel.n = ((float) rand() / RAND_MAX) < ((float) x / dimX); pixel.n = ((float) rand() / RAND_MAX) < ((float) x / dimX);
image.s_pixel(x, y, pixel); image.s_pixel(x, y, pixel);
} }
} }
return image; return image;
} }
int appliquer(Image &image, string nomFichier, string ID, bool ASCII) { int appliquer(Image &image, string nomFichier, bool ASCII) {
ouvrir(image, "tests/" + nomFichier); ouvrir(image, "tests/" + nomFichier);
sauver(image, "tests/" + ID, ASCII, nomFichier); Pixel pixel;
image.g_pixel(image.g_dimensionX() / 2, image.g_dimensionY() / 2, pixel);
// trait(image, image, image.g_dimensionX() / 4, image.g_dimensionY() / 4,
// image.g_dimensionX() - image.g_dimensionX() / 4,
// image.g_dimensionY() - image.g_dimensionY() / 4, pixel);
// cercle(image, image, image.g_dimensionX() / 2, image.g_dimensionY() / 2,
// image.g_dimensionY() / 4, pixel);
// disque(image, image, image.g_dimensionX() / 2, image.g_dimensionY() / 2,
// image.g_dimensionY() / 4, pixel);
// redimensionner(image, image, image.g_dimensionX() / 4, image.g_dimensionY() / 4,
// image.g_dimensionX() - image.g_dimensionX() / 4,
// image.g_dimensionY() - image.g_dimensionY() / 4);
// redimensionner(image, image, 0, 0, image.g_dimensionY(), image.g_dimensionY());
// retourner(image, image, 3);
// convBIN(image, image);
// convNIV(image, image);
// convRVB(image, image);
sauver(image, "tests/E_" + nomFichier, ASCII, nomFichier);
afficherImage(image); afficherImage(image);
attendreFenetre(); attendreFenetre();
} }
int main(int argc, char *args[]) { int main(int argc, char *args[]) {
#if defined(WIN32) // Permet de refaire fonctionner cout et cerr sous Windows après démarrage de SDL #if defined(WIN32) // Permet de refaire fonctionner cout et cerr sous Windows après démarrage de SDL
freopen("CON", "w", stdout); freopen("CON", "w", stdout);
freopen("CON", "w", stderr); freopen("CON", "w", stderr);
#endif #endif
presentation(); presentation();
cout << "Éxecution des instructions dans testing.cpp." << endl << endl;
#define DIMENSIONS 50 #define DIMENSIONS 50
Image image1 = genererRoue(DIMENSIONS*2, DIMENSIONS, 255); Image image1 = genererRoue(DIMENSIONS * 2, DIMENSIONS, 255);
Image image2 = genererRoue(DIMENSIONS*2, DIMENSIONS, 255); Image image2 = genererRoue(DIMENSIONS * 2, DIMENSIONS, 255);
// Image image1; // Tester si ça marche // Image image1; // Tester si ça marche
// afficherImage(image1); // afficherImage(image1);
// attendreFenetre(); // attendreFenetre();
// // Roue // // Roue
// Image image = image1.g_vide(); // Image image = image1.g_vide();
// for (float i = 0; i < 2 * PI; i += 0.1) { // for (float i = 0; i < 2 * PI; i += 0.1) {
// pivoter(image1, image, DIMENSIONS/2, DIMENSIONS/2, i); // pivoter(image1, image, DIMENSIONS/2, DIMENSIONS/2, i);
// afficherImage(image); // afficherImage(image);
// } // }
// Ouvrir fichier // Ouvrir fichier
appliquer(image1, "PikachuP1.pbm", "1", true); appliquer(image1, "PikachuP1.pbm", true);
appliquer(image1, "PikachuP2.pgm", "2", true); appliquer(image1, "PikachuP2.pgm", true);
appliquer(image1, "PikachuP3.ppm", "3", true); appliquer(image1, "PikachuP3.ppm", true);
appliquer(image1, "PikachuP4.pbm", "4", false); appliquer(image1, "PikachuP4.pbm", false);
appliquer(image1, "PikachuP5.pgm", "5", false); appliquer(image1, "PikachuP5.pgm", false);
appliquer(image1, "PikachuP6.ppm", "6", false); appliquer(image1, "PikachuP6.pgm", false);
// // Neige en dégradé // // Neige en dégradé
// for (int i; i < 300; i++) { // for (int i; i < 300; i++) {
// afficherImage(genererBruit(200, 200)); // afficherImage(genererBruit(200, 200));
// } // }
// Cycle de couleurs avec utilisation d'Image // Cycle de couleurs avec utilisation d'Image
// Image imageRoue(dimX, dimY, 255, PILG_RVB); // Image imageRoue(dimX, dimY, 255, PILG_RVB);
// Pixel pointRoueRoue = imageRoue.g_pixelVide(); // Pixel pointRoueRoue = imageRoue.g_pixelVide();
@ -164,7 +191,6 @@ int main(int argc, char *args[]) {
// } // }
// afficherFenetre(); // afficherFenetre();
// } // }
// // Cycle de couleurs sans utilisation d'Image // // Cycle de couleurs sans utilisation d'Image
// int x, y, c; // int x, y, c;
// for (c = 0; c < 256; c++) { // À peu près 75 FPS avec SDL // for (c = 0; c < 256; c++) { // À peu près 75 FPS avec SDL
@ -175,10 +201,7 @@ int main(int argc, char *args[]) {
// } // }
// afficherFenetre(); // afficherFenetre();
// } // }
// cout << "Éxecution du programme terminée. Vous pouvez quitter la fenêtre." << endl; // cout << "Éxecution du programme terminée. Vous pouvez quitter la fenêtre." << endl;
fermerFenetre(); fermerFenetre();
return 0; return 0;
} }

View file

@ -7,28 +7,27 @@
typedef enum {PILG_TYPE, PILG_DIMENSIONS, PILG_MAXCOMPOSANTE, PILG_IMAGE} PILG_OuvrirEtape; typedef enum {PILG_TYPE, PILG_DIMENSIONS, PILG_MAXCOMPOSANTE, PILG_IMAGE} PILG_OuvrirEtape;
// Gestion de fichiers // Gestion de fichiers
int creer(Image &sortie, int dimensionX, int dimensionY, int maxComposante, PILG_Comp typeComposantes) { // Créer une image de dimensions X et Y int creer(Image &sortie, int dimensionX, int dimensionY, int maxComposante,
PILG_Comp typeComposantes) { // Créer une image de dimensions X et Y
sortie = *new Image(dimensionX, dimensionY, maxComposante, typeComposantes); sortie = *new Image(dimensionX, dimensionY, maxComposante, typeComposantes);
return 0; return 0;
} }
int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à partir du nom du fichier ***Geoffrey int ouvrir(Image &sortie,
string nomFichier) { // Ouvrir une image existante à partir du nom du fichier
// Ouverture du fichier // Ouverture du fichier
#if DEBUG journal << "" << nomFichier << endl;
cout << "" << nomFichier << endl;
#endif
ifstream streamFichier(nomFichier.c_str(), ios::in); ifstream streamFichier(nomFichier.c_str(), ios::in);
if (streamFichier) { if (streamFichier) {
// Calcul de la taille (en octets) du fichier // Calcul de la taille (en octets) du fichier
streamFichier.seekg(0, ios::end); streamFichier.seekg(0, ios::end);
int tailleFichier (streamFichier.tellg()); int tailleFichier(streamFichier.tellg());
// Stockage du fichier dans une chaîne // Stockage du fichier dans une chaîne
streamFichier.seekg(0, ios::beg); streamFichier.seekg(0, ios::beg);
char *fichier_caracteres = new char [tailleFichier]; char *fichier_caracteres = new char [tailleFichier];
streamFichier.read(fichier_caracteres, tailleFichier); streamFichier.read(fichier_caracteres, tailleFichier);
streamFichier.close(); streamFichier.close();
// Variables d'informations // Variables d'informations
char cara; char cara;
PILG_OuvrirEtape ouvrirEtape(PILG_TYPE); PILG_OuvrirEtape ouvrirEtape(PILG_TYPE);
@ -37,7 +36,6 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
int dimensionY; int dimensionY;
int maxComposante; int maxComposante;
PILG_Comp typeComposantes; PILG_Comp typeComposantes;
// Variables de traitement du fichier // Variables de traitement du fichier
string element(""); string element("");
int x(0); int x(0);
@ -45,13 +43,15 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
int i(0); int i(0);
Pixel pixel; Pixel pixel;
string tmpASCII; string tmpASCII;
char RVBcomposante(0); // Composante actuelle pour RVB char RVBcomposante(0); // Composante actuelle pour RVB
for (int c(0); c < tailleFichier; c++) { for (int c(0); c < tailleFichier; c++) {
cara = fichier_caracteres[c]; cara = fichier_caracteres[c];
if (ouvrirEtape != PILG_IMAGE) { if (ouvrirEtape != PILG_IMAGE) {
if (cara == FICHIER_SEPARATEUR) { // En cas de nouvel élément if (cara == FICHIER_SEPARATEUR) { // En cas de nouvel élément
if (element[0] != '#') { // Si c'est un commentaire, on passe à l'élément suivant if (element[0] !=
'#') { // Si c'est un commentaire, on passe à l'élément suivant
switch (ouvrirEtape) { switch (ouvrirEtape) {
case PILG_TYPE: case PILG_TYPE:
if (element.length() == 2 && element[0] == 'P') { if (element.length() == 2 && element[0] == 'P') {
@ -60,29 +60,35 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
case '4': case '4':
typeComposantes = PILG_BIN; typeComposantes = PILG_BIN;
break; break;
case '2': case '2':
case '5': case '5':
typeComposantes = PILG_NIV; typeComposantes = PILG_NIV;
break; break;
case '3': case '3':
case '6': case '6':
typeComposantes = PILG_RVB; typeComposantes = PILG_RVB;
break; break;
default: default:
return 3; return 3;
break; break;
} }
switch (element[1]) { switch (element[1]) {
case '1': case '1':
case '2': case '2':
case '3': case '3':
ASCII = true; ASCII = true;
break; break;
case '4': case '4':
case '5': case '5':
case '6': case '6':
ASCII = false; ASCII = false;
break; break;
default: default:
return 3; return 3;
break; break;
@ -90,17 +96,19 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
} else { } else {
return 3; return 3;
} }
ouvrirEtape = PILG_DIMENSIONS; ouvrirEtape = PILG_DIMENSIONS;
#if DEBUG journal << "Type de fichier : " << element << " (" << ((
cout << "Type de fichier : " << element << " (" << ((typeComposantes == 0) ? "Noir et Blanc" : ((typeComposantes == 1) ? "Niveaux de gris" : "Rouge / Vert / Bleu")) << ", " << (ASCII ? "ASCII" : "Brut") << ")" << endl; typeComposantes == 0) ? "Noir et Blanc" : ((typeComposantes == 1) ?
#endif "Niveaux de gris" : "Rouge / Vert / Bleu")) << ", " << (ASCII ? "ASCII" :
"Brut") << ")" << endl;
break; break;
case PILG_DIMENSIONS: { case PILG_DIMENSIONS: {
bool espaceDepasse(false); bool espaceDepasse(false);
string dimensionXchaine(""); string dimensionXchaine("");
string dimensionYchaine(""); string dimensionYchaine("");
for (int j(0); j < element.size(); j++) { for (int j(0); j < element.size(); j++) {
if (element[j] == ' ') { if (element[j] == ' ') {
espaceDepasse = true; espaceDepasse = true;
@ -110,14 +118,17 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
dimensionXchaine += element[j]; dimensionXchaine += element[j];
} }
} }
chaineVersEntier(dimensionXchaine, dimensionX); chaineVersEntier(dimensionXchaine, dimensionX);
chaineVersEntier(dimensionYchaine, dimensionY); chaineVersEntier(dimensionYchaine, dimensionY);
if (!espaceDepasse || dimensionX == 0 || dimensionY == 0) { if (!espaceDepasse || dimensionX == 0 || dimensionY == 0) {
return 5; return 5;
} }
#if DEBUG
cout << "Dimensions : " << dimensionX << " px / " << dimensionY << "px" << endl; journal << "Dimensions : " << dimensionX << " px / " << dimensionY << "px" <<
#endif endl;
if (typeComposantes == PILG_BIN) { if (typeComposantes == PILG_BIN) {
ouvrirEtape = PILG_IMAGE; ouvrirEtape = PILG_IMAGE;
} else { } else {
@ -125,23 +136,26 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
} }
} }
break; break;
case PILG_MAXCOMPOSANTE: case PILG_MAXCOMPOSANTE:
chaineVersEntier(element, maxComposante); chaineVersEntier(element, maxComposante);
#if DEBUG journal << "Maximum de composante" << ((typeComposantes == 2) ? "s" : "") <<
cout << "Maximum de composante" << ((typeComposantes == 2) ? "s" : "") << " : " << maxComposante << endl; " : "
#endif << maxComposante << endl;
ouvrirEtape = PILG_IMAGE; ouvrirEtape = PILG_IMAGE;
break; break;
default: default:
return 4; return 4;
break; break;
} }
if (ouvrirEtape == PILG_IMAGE) { if (ouvrirEtape == PILG_IMAGE) {
sortie = *new Image(dimensionX, dimensionY, maxComposante, typeComposantes); sortie = *new Image(dimensionX, dimensionY, maxComposante, typeComposantes);
pixel = sortie.g_pixelVide(); pixel = sortie.g_pixelVide();
} }
} }
element = ""; element = "";
} else { } else {
element += cara; element += cara;
@ -162,10 +176,12 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
chaineVersEntier(tmpASCII, pixel.r); chaineVersEntier(tmpASCII, pixel.r);
RVBcomposante = 1; RVBcomposante = 1;
break; break;
case 1: case 1:
chaineVersEntier(tmpASCII, pixel.v); chaineVersEntier(tmpASCII, pixel.v);
RVBcomposante = 2; RVBcomposante = 2;
break; break;
case 2: case 2:
chaineVersEntier(tmpASCII, pixel.b); chaineVersEntier(tmpASCII, pixel.b);
RVBcomposante = 0; RVBcomposante = 0;
@ -178,11 +194,11 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
sortie.s_pixel(x, y, pixel); sortie.s_pixel(x, y, pixel);
x++; x++;
} }
tmpASCII = ""; tmpASCII = "";
} else { } else {
tmpASCII += cara; tmpASCII += cara;
} }
} }
} else { } else {
if (typeComposantes == PILG_BIN) { if (typeComposantes == PILG_BIN) {
@ -190,6 +206,7 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
pixel.n = !((cara >> i) & 0x01); pixel.n = !((cara >> i) & 0x01);
sortie.s_pixel(x, y, pixel); sortie.s_pixel(x, y, pixel);
x++; x++;
if (x >= dimensionX) { if (x >= dimensionX) {
y++; y++;
x = 0; x = 0;
@ -202,10 +219,12 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
pixel.r = caraVersEntier(cara); pixel.r = caraVersEntier(cara);
RVBcomposante = 1; RVBcomposante = 1;
break; break;
case 1: case 1:
pixel.v = caraVersEntier(cara); pixel.v = caraVersEntier(cara);
RVBcomposante = 2; RVBcomposante = 2;
break; break;
case 2: case 2:
pixel.b = caraVersEntier(cara); pixel.b = caraVersEntier(cara);
RVBcomposante = 0; RVBcomposante = 0;
@ -220,6 +239,7 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
} }
} }
} }
if (x >= dimensionX) { if (x >= dimensionX) {
y++; y++;
x += -dimensionX; x += -dimensionX;
@ -229,45 +249,54 @@ int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à
} else { } else {
return 1; return 1;
} }
#if DEBUG
cout << endl; journal << endl;
#endif
return 0; return 0;
} }
int sauver(Image entree, string nomFichier, bool ASCII, string commentaire) { // Sauvegarder l'image obtenue dans un nouveau fichier int sauver(Image entree, string nomFichier, bool ASCII,
string commentaire) { // Sauvegarder l'image obtenue dans un nouveau fichier
ofstream fichier(nomFichier.c_str(), ios::out | ios::trunc); ofstream fichier(nomFichier.c_str(), ios::out | ios::trunc);
char numero; char numero;
switch (entree.g_typeComposantes()) { switch (entree.g_typeComposantes()) {
case PILG_BIN: case PILG_BIN:
numero = ASCII ? '1' : '4'; numero = ASCII ? '1' : '4';
break; break;
case PILG_NIV: case PILG_NIV:
numero = ASCII ? '2' : '5'; numero = ASCII ? '2' : '5';
break; break;
case PILG_RVB: case PILG_RVB:
numero = ASCII ? '3' : '6'; numero = ASCII ? '3' : '6';
break; break;
default: default:
return 1; return 1;
} }
fichier << "P" << numero << FICHIER_SEPARATEUR; fichier << "P" << numero << FICHIER_SEPARATEUR;
if (commentaire != "") { if (commentaire != "") {
fichier << "# " << commentaire << FICHIER_SEPARATEUR; fichier << "# " << commentaire << FICHIER_SEPARATEUR;
} }
fichier << entree.g_dimensionX() << " " << entree.g_dimensionY() << FICHIER_SEPARATEUR;
fichier << entree.g_dimensionX() << " " << entree.g_dimensionY() <<
FICHIER_SEPARATEUR;
if (entree.g_typeComposantes() != PILG_BIN) { if (entree.g_typeComposantes() != PILG_BIN) {
fichier << entree.g_maxComposante() << FICHIER_SEPARATEUR;; fichier << entree.g_maxComposante() << FICHIER_SEPARATEUR;;
} }
Pixel pixel; Pixel pixel;
char brutBINpixel; char brutBINpixel;
int brutBINpixelRang = 7; int brutBINpixelRang = 7;
for (int y = 0; y < entree.g_dimensionY(); y++) { for (int y = 0; y < entree.g_dimensionY(); y++) {
for (int x = 0; x < entree.g_dimensionX(); x++) { for (int x = 0; x < entree.g_dimensionX(); x++) {
entree.g_pixel(x, y, pixel); entree.g_pixel(x, y, pixel);
switch (entree.g_typeComposantes()) { switch (entree.g_typeComposantes()) {
case PILG_BIN: case PILG_BIN:
if (ASCII) { if (ASCII) {
@ -282,34 +311,45 @@ int sauver(Image entree, string nomFichier, bool ASCII, string commentaire) { //
} else { } else {
brutBINpixel |= 1 << brutBINpixelRang; brutBINpixel |= 1 << brutBINpixelRang;
} }
brutBINpixelRang--; brutBINpixelRang--;
if (brutBINpixelRang < 0) { if (brutBINpixelRang < 0) {
fichier << brutBINpixel; fichier << brutBINpixel;
brutBINpixelRang = 7; brutBINpixelRang = 7;
} }
} }
break; break;
case PILG_NIV: case PILG_NIV:
if (ASCII) { if (ASCII) {
fichier << pixel.g << FICHIER_SEPARATEUR; fichier << pixel.g << FICHIER_SEPARATEUR;
} else { } else {
fichier << (char) pixel.g; fichier << (char) pixel.g;
} }
break; break;
case PILG_RVB: case PILG_RVB:
if (ASCII) { if (ASCII) {
fichier << pixel.r << FICHIER_SEPARATEUR << pixel.v << FICHIER_SEPARATEUR << pixel.b << FICHIER_SEPARATEUR; fichier << pixel.r << FICHIER_SEPARATEUR
<< pixel.v << FICHIER_SEPARATEUR
<< pixel.b << FICHIER_SEPARATEUR;
} else { } else {
fichier << (char) pixel.r fichier << (char) pixel.r
<< (char) pixel.v << (char) pixel.v
<< (char) pixel.b; << (char) pixel.b;
} }
break; break;
default: default:
return 1; return 1;
} }
} }
} }
fichier.close(); fichier.close();
return 0; return 0;
} }
@ -323,100 +363,99 @@ int importer(Image entree, Image &sortie, string nomFichier, int x, int y) {
// sortie.s_pixel(x1 + x, y1 + y, fichierImporte.g_pixel(x1, x2)); // sortie.s_pixel(x1 + x, y1 + y, fichierImporte.g_pixel(x1, x2));
// FinPour // FinPour
// FinPour // FinPour
return 1; return 1;
} }
// Couleur // Couleur
int teinte(Image entree, Image &sortie, float teinte) { // Change la teinte de l'image int teinte(Image entree, Image &sortie,
// for (int x = 0, x = image.g_DimensionX(), x++) { float teinte) { // Change la teinte de l'image
// for (int y = 0, y = image.g_DimensionY(), y++) { // for (int x = 0, x = image.g_dimensionX(), x++) {
// for (int y = 0, y = image.g_dimensionY(), y++) {
// rvbVersTsl(); // rvbVersTsl();
// g_pixel(x, y); // g_pixel(x, y);
// } // }
// } // }
// return 1; // return 1;
} }
int saturation(Image entree, Image &sortie, float saturation) { // Sature l'image int saturation(Image entree, Image &sortie,
float saturation) { // Sature l'image
// Utilisation de la méthode TSL // Utilisation de la méthode TSL
return 1; return 1;
} }
int luminosite(Image entree, Image &sortie, float luminosite) { // Augmente la luminosité de l'image int luminosite(Image entree, Image &sortie,
float luminosite) { // Augmente la luminosité de l'image
// Utilisation de la méthode TSL // Utilisation de la méthode TSL
return 1; return 1;
} }
int contraste(Image entree, Image &sortie, float contraste) { // Accentue les contrastes de l'image int contraste(Image entree, Image &sortie,
float contraste) { // Accentue les contrastes de l'image
// À voir // À voir
return 1; return 1;
} }
// Dessin // Dessin
int trait(Image entree, Image &sortie, int x1, int y1, int x2, int y2, Pixel couleur) { // Dessine un trait d'un point (x1,y1) à un point (x2,y2) int trait(Image entree, Image &sortie, int x1, int y1, int x2, int y2,
// int x, y, dx, dy; Pixel couleur) { // Dessine un trait d'un point (x1,y1) à un point (x2,y2)
// float e, e(1, 0), e(0, 1) ; // valeur derreur et incréments int x;
// dy = y2 - y1 ; sortie = entree;
// dx = x2 - x1 ;
// y = y1 ; // rangée initiale for (x = 0; x <= x2 - x1; x++) {
// e = 0, 0 ; // valeur derreur initiale // cout << "(" << x << ";__) a=" << ((float) x / (x2 - x1)) << " yD=" <<
// e(1, 0) = dy / dx ; // (y2 - y1) * ((float)x / (x2 - x1)) << endl;
// e(0, 1) = -1.0 ; sortie.s_pixel(x1 + x, y1 + (y2 - y1) * ((float) x / (x2 - x1)), couleur);
// for (x = x1; x <= x2; x++) { }
// sortie.s_pixel(x, y, couleur);
// if ((e = e + e(1, 0)) >= 0, 5) { // erreur pour le pixel suivant de même rangée return 0;
// y = y + 1 ; // choisir plutôt le pixel suivant dans la rangée supérieure
// e = e + e(0, 1) ; // ajuste lerreur commise dans cette nouvelle rangée
// }
// }
// return 0;
return 1;
} }
int rectangle(Image entree, Image &sortie, int x1, int y1, int x2, int y2, Pixel couleur) { int rectangle(Image entree, Image &sortie, int x1, int y1, int x2, int y2,
Pixel couleur) {
sortie = entree; sortie = entree;
for (int x = x1; x <= x2; x++) { for (int x = x1; x <= x2; x++) {
for (int y = y1; y <= y2; y++) { for (int y = y1; y <= y2; y++) {
sortie.s_pixel(x, y, couleur); sortie.s_pixel(x, y, couleur);
} }
} }
return 0; return 0;
} }
int cercle(Image entree, Image &sortie, int x0, int y0, int r, Pixel couleur) { int cercle(Image entree, Image &sortie, int x0, int y0, int r, Pixel couleur) {
sortie = entree; sortie = entree;
for (int x = 0; x <= entree.g_dimensionX(); x++) { for (int x = 0; x <= entree.g_dimensionX(); x++) {
for (int y = 0; y <= entree.g_dimensionY(); y++) { for (int y = 0; y <= entree.g_dimensionY(); y++) {
if (sqrt(pow(x - x0, 2) + pow(y - y0, 2)) == r) { if ((int) sqrt(pow(x - x0, 2) + pow(y - y0, 2)) == r) {
sortie.s_pixel(x, y, couleur); sortie.s_pixel(x, y, couleur);
} }
} }
} }
return 0; return 0;
} }
int disque(Image entree, Image &sortie, int x0, int y0, int r, Pixel couleur) { int disque(Image entree, Image &sortie, int x0, int y0, int r, Pixel couleur) {
sortie = entree; sortie = entree;
for (int x = 0; x <= entree.g_dimensionX(); x++) { for (int x = 0; x <= entree.g_dimensionX(); x++) {
for (int y = 0; y <= entree.g_dimensionY(); y++) { for (int y = 0; y <= entree.g_dimensionY(); y++) {
if (sqrt(pow(x - x0, 2) + pow(y - y0, 2)) <= r) { if ((int) sqrt(pow(x - x0, 2) + pow(y - y0, 2)) <= r) {
sortie.s_pixel(x, y, couleur); sortie.s_pixel(x, y, couleur);
} }
} }
} }
return 0; return 0;
} }
// Geométrie // Geométrie
int zoom(Image entree, Image &sortie) { int zoom(Image entree, Image &sortie) {
return 1; return 1;
} }
@ -424,6 +463,7 @@ int pivoter(Image entree, Image &sortie, int x0, int y0, float angle) {
sortie = entree.g_vide(); sortie = entree.g_vide();
float xF, yF, angleF, xI, yI, angleI, h; float xF, yF, angleF, xI, yI, angleI, h;
Pixel pixel = entree.g_pixelVide(); Pixel pixel = entree.g_pixelVide();
for (xF = 0; xF < entree.g_dimensionX(); xF++) { for (xF = 0; xF < entree.g_dimensionX(); xF++) {
for (yF = 0; yF < entree.g_dimensionY(); yF++) { for (yF = 0; yF < entree.g_dimensionY(); yF++) {
if (xF == x0 && yF == y0) { if (xF == x0 && yF == y0) {
@ -437,28 +477,72 @@ int pivoter(Image entree, Image &sortie, int x0, int y0, float angle) {
xI = cos(angleI) * h + x0; xI = cos(angleI) * h + x0;
yI = sin(angleI) * h + y0; yI = sin(angleI) * h + y0;
} }
entree.g_pixel((int) xI, (int) yI, pixel); entree.g_pixel((int) xI, (int) yI, pixel);
sortie.s_pixel((int) xF, (int) yF, pixel); sortie.s_pixel((int) xF, (int) yF, pixel);
} }
} }
return 0;
}
int retourner(Image entree, Image &sortie, int rotation) {
rotation = rotation % 4;
int x, y;
Pixel pixel;
if (rotation == 0) {
sortie = entree;
} else {
if (rotation == 2) {
sortie = entree.g_vide();
} else {
sortie = *new Image(entree.g_dimensionY(), entree.g_dimensionX(),
entree.g_maxComposante(), entree.g_typeComposantes());
}
for (x = 0; x < entree.g_dimensionX(); x++) {
for (y = 0; y < entree.g_dimensionY(); y++) {
entree.g_pixel(x, y, pixel);
switch (rotation) {
case 1:
sortie.s_pixel(entree.g_dimensionY() - y - 1, x, pixel);
break;
case 2:
journal << "5";
sortie.s_pixel(entree.g_dimensionX() - x - 1, entree.g_dimensionY() - y - 1,
pixel);
break;
case 3:
sortie.s_pixel(y, entree.g_dimensionX() - x - 1, pixel);
break;
default:
journal << "6";
return 1;
}
}
}
}
return 0; return 0;
} }
int retourner(Image entree, Image &sortie, int rotation) { int redimensionner(Image entree, Image &sortie, int x1, int y1, int x2,
int y2) {
return 1; sortie = *new Image(x2 - x1, y2 - y1, entree.g_maxComposante(),
} entree.g_typeComposantes());
Pixel pixel;
int redimensionner(Image entree, Image &sortie, int x1, int x2, int y1, int y2) {
for (int x = 0; x <= x2 - x1; x++) {
sortie = *new Image(x2 - x1, y2 - y1, entree.g_maxComposante(), entree.g_typeComposantes()); for (int y = 0; y <= y2 - y1; y++) {
Pixel pixel = entree.g_pixelVide(); entree.g_pixel(x1 + x, y1 + y, pixel);
for (int x = x1; x <= x2; x++) {
for (int y = y1; y <= y2; y++) {
entree.g_pixel(x + x1, y + y1, pixel);
sortie.s_pixel(x, y, pixel); sortie.s_pixel(x, y, pixel);
} }
} }
return 0; return 0;
} }
@ -470,23 +554,30 @@ int convBIN(Image entree, Image &sortie) {
sortie = *new Image(entree.g_dimensionX(), entree.g_dimensionY(), 0, PILG_BIN); sortie = *new Image(entree.g_dimensionX(), entree.g_dimensionY(), 0, PILG_BIN);
Pixel pixelI, pixelF; Pixel pixelI, pixelF;
pixelF = sortie.g_pixelVide(); pixelF = sortie.g_pixelVide();
for (int x = 0; x <= entree.g_dimensionX(); x++) { for (int x = 0; x <= entree.g_dimensionX(); x++) {
for (int y = 0; y <= entree.g_dimensionY(); y++) { for (int y = 0; y <= entree.g_dimensionY(); y++) {
entree.g_pixel(x, y, pixelI); entree.g_pixel(x, y, pixelI);
switch (entree.g_typeComposantes()) { switch (entree.g_typeComposantes()) {
case PILG_NIV: case PILG_NIV:
pixelF.n = (pixelI.g > entree.g_maxComposante() / 2); pixelF.n = (pixelI.g > (entree.g_maxComposante() / 2));
break; break;
case PILG_RVB: case PILG_RVB:
pixelF.n = ((pixelI.r + pixelI.v + pixelI.b) / 3 > entree.g_maxComposante() / 2); pixelF.n = ((pixelI.r + pixelI.v + pixelI.b) / 3 > (entree.g_maxComposante() /
2));
break; break;
default: default:
return 2; return 2;
} }
sortie.s_pixel(x, y, pixelF); sortie.s_pixel(x, y, pixelF);
} }
} }
} }
return 0; return 0;
} }
@ -494,35 +585,74 @@ int convNIV(Image entree, Image &sortie) {
if (entree.g_typeComposantes() == PILG_NIV) { if (entree.g_typeComposantes() == PILG_NIV) {
sortie = entree; sortie = entree;
} else { } else {
sortie = *new Image(entree.g_dimensionX(), entree.g_dimensionY(), MAXCOMPOSANTEDEFAUT, PILG_NIV); sortie = *new Image(entree.g_dimensionX(), entree.g_dimensionY(),
MAXCOMPOSANTEDEFAUT, PILG_NIV);
Pixel pixelI, pixelF; Pixel pixelI, pixelF;
pixelF = sortie.g_pixelVide(); pixelF = sortie.g_pixelVide();
for (int x = 0; x <= entree.g_dimensionX(); x++) { for (int x = 0; x <= entree.g_dimensionX(); x++) {
for (int y = 0; y <= entree.g_dimensionY(); y++) { for (int y = 0; y <= entree.g_dimensionY(); y++) {
entree.g_pixel(x, y, pixelI); entree.g_pixel(x, y, pixelI);
switch (entree.g_typeComposantes()) { switch (entree.g_typeComposantes()) {
case PILG_BIN: case PILG_BIN:
pixelF.g = (pixelI.n ? sortie.g_maxComposante() : 0); pixelF.g = (pixelI.n ? sortie.g_maxComposante() : 0);
break; break;
case PILG_RVB: case PILG_RVB:
pixelF.g = (pixelI.r + pixelI.v + pixelI.b) / 3.0 / entree.g_maxComposante() * sortie.g_maxComposante(); pixelF.g = (pixelI.r + pixelI.v + pixelI.b) / 3.0 / entree.g_maxComposante() *
sortie.g_maxComposante();
break; break;
default: default:
return 1; return 1;
} }
sortie.s_pixel(x, y, pixelF); sortie.s_pixel(x, y, pixelF);
} }
} }
} }
return 0; return 0;
} }
int convRVB(Image entree, Image &sortie) { int convRVB(Image entree, Image &sortie) {
return 1; if (entree.g_typeComposantes() == PILG_RVB) {
sortie = entree;
} else {
sortie = *new Image(entree.g_dimensionX(), entree.g_dimensionY(),
MAXCOMPOSANTEDEFAUT, PILG_RVB);
Pixel pixelI, pixelF;
pixelF = sortie.g_pixelVide();
for (int x = 0; x <= entree.g_dimensionX(); x++) {
for (int y = 0; y <= entree.g_dimensionY(); y++) {
entree.g_pixel(x, y, pixelI);
switch (entree.g_typeComposantes()) {
case PILG_BIN:
pixelF.r = pixelF.v = pixelF.b = (pixelI.n ? sortie.g_maxComposante() : 0);
break;
case PILG_NIV:
pixelF.r = pixelF.v = pixelF.b = (float) pixelI.g / entree.g_maxComposante() *
sortie.g_maxComposante();
break;
default:
return 1;
}
sortie.s_pixel(x, y, pixelF);
}
}
}
return 0;
} }
//Help // Aide
int aide() { int aide() {
//Afficher le texte suivant : // Afficher le texte suivant :
return 1; return 1;
} }

View file

@ -1,14 +1,16 @@
#include <math.h> #include <math.h>
#include <fstream>
#define NOMBREOR 1.61803398875 #define NOMBREOR 1.61803398875
ofstream journal("PILG-log.txt", ios::out | ios::trunc);
void presentation() { void presentation() {
cout << " ____ ___ _ ____ " << endl cout << " ____ ___ _ ____ " << endl
<< "| _ \\|_ _|| | / ___|" << endl << "| _ \\|_ _|| | / ___|" << endl
<< "| |_) || | | | | | _ " << endl << "| |_) || | | | | | _ " << endl
<< "| __/ | | | |___| |_| |" << endl << "| __/ | | | |___| |_| |" << endl
<< "|_| |___||_____|\\____|" << endl << "|_| |___||_____|\\____|" << endl;
<< endl;
} }
Image imageDefaut() { Image imageDefaut() {
@ -17,70 +19,133 @@ Image imageDefaut() {
Pixel pointRoue = imageRoue.g_pixelVide(); Pixel pointRoue = imageRoue.g_pixelVide();
int x, y, step; int x, y, step;
float substep, lum; float substep, lum;
for (x = 0; x < dimX; x++) { for (x = 0; x < dimX; x++) {
for (y = 0; y < dimY; y++) { for (y = 0; y < dimY; y++) {
step = (x * 6.0) / dimX; step = (x * 6.0) / dimX;
substep = (x - step * (dimX / 6.0)) / (dimX / 6.0) * maxComposante; substep = (x - step * (dimX / 6.0)) / (dimX / 6.0) * maxComposante;
lum = 1 - ((float) y) / dimY; lum = 1 - ((float) y) / dimY;
switch (step) { switch (step) {
case 0: case 0:
pointRoue.r = maxComposante; pointRoue.r = maxComposante;
pointRoue.v = substep; pointRoue.v = substep;
pointRoue.b = 0; pointRoue.b = 0;
break; break;
case 1: case 1:
pointRoue.r = maxComposante - substep; pointRoue.r = maxComposante - substep;
pointRoue.v = maxComposante; pointRoue.v = maxComposante;
pointRoue.b = 0; pointRoue.b = 0;
break; break;
case 2: case 2:
pointRoue.r = 0; pointRoue.r = 0;
pointRoue.v = maxComposante; pointRoue.v = maxComposante;
pointRoue.b = substep; pointRoue.b = substep;
break; break;
case 3: case 3:
pointRoue.r = 0; pointRoue.r = 0;
pointRoue.v = maxComposante - substep; pointRoue.v = maxComposante - substep;
pointRoue.b = maxComposante; pointRoue.b = maxComposante;
break; break;
case 4: case 4:
pointRoue.r = substep; pointRoue.r = substep;
pointRoue.v = 0; pointRoue.v = 0;
pointRoue.b = maxComposante; pointRoue.b = maxComposante;
break; break;
case 5: case 5:
pointRoue.r = maxComposante; pointRoue.r = maxComposante;
pointRoue.v = 0; pointRoue.v = 0;
pointRoue.b = maxComposante - substep; pointRoue.b = maxComposante - substep;
break; break;
default: default:
pointRoue.r = pointRoue.v = pointRoue.b = 0; pointRoue.r = pointRoue.v = pointRoue.b = 0;
} }
// Dégradé vers le noir // Dégradé vers le noir
pointRoue.r = pointRoue.r * lum; pointRoue.r = pointRoue.r * lum;
pointRoue.v = pointRoue.v * lum; pointRoue.v = pointRoue.v * lum;
pointRoue.b = pointRoue.b * lum; pointRoue.b = pointRoue.b * lum;
imageRoue.s_pixel(x, y, pointRoue); imageRoue.s_pixel(x, y, pointRoue);
} }
} }
return imageRoue; return imageRoue;
} }
void afficherImage(Image image) {
#define ECHELLE 1
int x, y, r, v, b, eX, eY, dimensionX = image.g_dimensionX() * ECHELLE,
dimensionY = image.g_dimensionY() * ECHELLE,
typeComposantes = image.g_typeComposantes();
float ratio = (255.0 / image.g_maxComposante());
Pixel pixel;
if (fenetreOuverte && (dimensionX != fenetreDimensionX ||
dimensionY != fenetreDimensionY)) {
fermerFenetre();
}
ouvrirFenetre(dimensionX, dimensionY, "PILG");
for (x = 0; x < image.g_dimensionX(); x++) {
for (y = 0; y < image.g_dimensionY(); y++) {
image.g_pixel(x, y, pixel);
switch (typeComposantes) {
case PILG_BIN:
r = v = b = (pixel.n ? 255 : 0);
break;
case PILG_NIV:
r = v = b = pixel.g * ratio;
break;
case PILG_RVB:
r = pixel.r * ratio;
v = pixel.v * ratio;
b = pixel.b * ratio;
break;
}
for (eX = 0; eX < ECHELLE; eX++) {
for (eY = 0; eY < ECHELLE; eY++) {
pointFenetre(x * ECHELLE + eX, y * ECHELLE + eY, r, v, b);
}
}
}
}
afficherFenetre();
}
void messageErreur(string message) {
cerr << "Erreur : " << message << '.' << endl;
journal << "Erreur : " << message << '.' << endl;
}
int chaineVersEntier(string chaine, int &entier) { int chaineVersEntier(string chaine, int &entier) {
entier = atoi(chaine.c_str()); entier = atoi(chaine.c_str());
if (entier == 0 && chaine != "0") { if (entier == 0 && chaine != "0") {
return 1; return 1;
} }
return 0; return 0;
} }
int chaineVersFlottant(string chaine, float &flottant) { int chaineVersFlottant(string chaine, float &flottant) {
flottant = atof(chaine.c_str()); flottant = atof(chaine.c_str());
if (flottant == 0 && chaine != "0") { if (flottant == 0 && chaine != "0") {
return 1; return 1;
} }
return 0; return 0;
} }
@ -88,8 +153,10 @@ int caraVersEntier(char cara) {
// int entier = (int) (0 << 8) + cara; // int entier = (int) (0 << 8) + cara;
// entier = entier > 0 ? entier : 256+entier; // entier = entier > 0 ? entier : 256+entier;
int i, entier = 0; int i, entier = 0;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
entier += ((cara >> i) & 0x01) ? pow(2, i) : 0; entier += ((cara >> i) & 0x01) ? pow(2, i) : 0;
} }
return entier; return entier;
} }