Compare commits

...
This repository has been archived on 2019-08-09. You can view files and clone it, but cannot push or open issues or pull requests.

19 commits

Author SHA1 Message Date
Geoffrey Frogeye 4700e225fb Ajouté les alias -r et -a
-r et -a agissent pour -v, ce qui est plus logique pour des angles et des rayons.
2014-05-24 21:29:40 +02:00
Geoffrey Frogeye 68694e3d73 Corrections des commandes couleurs
* Luminosité & Saturation : multiplication au lieu d'addition
* Le zéro de saturation était mal géré
2014-05-22 21:26:51 +02:00
Geoffrey Frogeye 82a60fccf9 [v1.0.0] Teinte, Saturation, Luminosité
Passage en v1.0.0 finale (il faut bien, à un moment...).
* Traitement image & commandes
	* Ajout de la fonction teinte
	* Ajout de la fonction saturation
	* Ajout de la fonction luminosité
* Utilitaires
	* Ajout de conversions RVB→TSL & TSL→RVB pour les fonctions teinte, saturation et luminosité
	* L'image par défaut est désormais générée à partir de teinte et luminosité
* Affichage de la fenêtre
	* La taille de l'écran est récupérable
	* L'échelle est désormais variable et est calculée selon les dimensions de l'écran
2014-05-22 20:14:36 +02:00
Geoffrey Frogeye 386ff0b51b Mise en utilisation des nouvelles commandes
Les commandes ajoutées dans le code sont désormais accessible depuis le programme, grâce à quelques modifications dans les différents arguments et beaucoup de copier/coller.
* Traitement de la commande
	* Ajout des arguments valeur (v1), booléen (b1), texte (t1), fichier (f1), entree (e), sortie (s), composante (p)
		* Toutes les valeurs (entier, floattant) sont désormais regroupées dans valeur
		* Entree et sortie sont des fichiers qui seront lus et écrits (respectivement) sans conditions (pour une utilisation sans REPL)
	* Ajout des commandes creer, ouvrir, sauver, trait, rectangle, cercle, disque, retourner, redimensionner, convRVB
	* Ajout et modification de quelques codes d'erreur
* Corrections et améliorations diverses
2014-05-20 22:15:37 +02:00
Geoffrey Frogeye a618bdaf42 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)
2014-05-20 20:00:32 +02:00
Geoffrey Frogeye 077ef18a41 Finalisation de ouvrir() et sauver()
Les fonctions marchent mais ne sont pas inclues dans les commandes disponibles, on fera ça avec tout le reste.
* traitementImage.cpp
	* La fonction créer est désormais complète
	* La fonction sauver est désormais complète
* utilitaires.cpp
	* Ajout d'une fonction caraVersEntier() pour convertir manuellement un octet vers un int. Nécessaire car la conversion par type était assez difficile à maitriser
* test.cpp
	* Ajout d'une fonction appliquer afin de faire des tests en série
* image.h
	* Les unsigned int sont désormais remis en int
Cela a permis d'éviter quelques bugs lors de l'ouverture et de la fermeture de fichiers. Ils pourraient potentiellement être remis, mais ils ne servent pas à grand chose au final à par compliquer la tâche.
* Rajout de utilitaires.cpp aux dépendances du Makefile
2014-05-19 22:43:59 +02:00
Geoffrey Frogeye 68b61139b8 Avancement sur l'ouverture et la fermeture de fichiers (demi-commit)
Contient les travaux de la séance du 19/05/2014 ainsi que de précédents travaux
* traitementImage.cpp
	* Ajout de la détection de l'en-tête et de ses informations dans la fonction ouvrir()
	* Ajout de la fonction sauver() (non-fonctionelle)
	* Mise en commentaire de la fonction trait() pour le moment
	* Correction des fonctions cercle(), disque() et redimensionner() (non-testées)
* Ajout d'un fichier utilitaires.cpp
	* Fonction presentation() qui montre un joli ASCII art
	* Déplacement de imageDefaut()
	* Déplacement de chaineVersXXX()
* testing.cpp
	* Ajout d'un dossier tests avec différentes images de test
	* Ajout d'instructions pour tester l'ouverture et la sauvegarde de fichiers
2014-05-19 17:37:00 +02:00
LuKiLL fbf5df1888 FAIL DE COMMIT 2014-05-19 11:41:42 +02:00
LuKiLL f06c222fa7 Update 3/4 séance 19/05/2014
Code de certaines fonctions.
2014-05-19 11:40:08 +02:00
Geoffrey Frogeye 1f5f2f9c91 [ALPHA] Fin du travail du 12/05/14
Des commandes qui fonctionnent vraiment ainsi quelques conversions entre types de composantes, cela suffit pour passer en alpha !
* Passage au stade d'alpha
Certaines commandes peuvent désormais être executées pleinement. On ne rajoutera pas de fonctionnalités (hormis les commandes) majeures.
* traitementImage.cpp
	* Mise en fonction de convBIN et convNIV
		* Correction de certaines erreurs
			* Travis devrait être content
		Note : convNIV et convRVB auront des valeurs par défaut en tant que maximum de composante, les fonctions n'étant pas très utiles à la base rien ne sert de les compliquer
	* Enième modification du type de fonctions
		* Resteront des int
		* Permet de prendre en compte les erreurs qui ne devraient normalement pas arriver
	* Passage de certaines lignes oubliées au formatteur
	* pivoter()
		* Suppression d'une stupidité mathématique (modulo 2π)
		(Semble plus rapide, sans raison apparente)
* analyseCommande.cpp
	* Les arguments sont désormais correctement analysés
	* pivoter, convBIN et convNIV peuvent désormais être appelé
	* Mise en fonction de chaineVersEntier()
	* Ajout de chaineVersFlottant()
	* Ajout de l'analyse de l'argument -angle
	* Ajout de l'analyse de l'argument -couleur
	* Ajout de messages d'erreurs correspondant à ce qui a été ennoncé précédement
2014-05-13 22:23:45 +02:00
Geoffrey Frogeye 425af05430 Update fin séance 12/05/2014
* Commencement des travaux sur l'analyse des arguments
* Ajout d'un Makefile pour Windows fonctionnel
On verra pour la correction du code plus tard.
2014-05-12 12:01:56 +02:00
LuKiLL 9bbdb6b3ee Update 3/4 séance 12/05/2014
Ajout des fonctions suivantes :
- Cercle ;
- Disque ;
- Conversion Binaire ;
- Conversion Niveaux de gris.
2014-05-12 11:33:32 +02:00
Geoffrey Frogeye 2af24e2cc8 Ajout de la fonction pivoter
* Ajout de la fonction pivoter()
* Ajout de Image::g_dupplicata()
* Corrections diverses, au Makefile notamment
2014-05-10 12:13:06 +02:00
Geoffrey Frogeye 43550b265f Avancement dans l'éxecution de commandes
Le programme dispose désormais d'une image par défaut affichée à l'écran. L'analyse de commandes a été travaillé, pour la tester la fonction rectangle fonctionne, sans arguments cependant, ce sera donc un carré prédéfini qui apparaitra sur l'image de test. Diverses améliorations notables cependant.

* Modifié main.cpp
	* Ajout d'une Image par défaut (sorte de roue chromatique horizontale) aux proportions d'or
* Modifié analyserCommande.cpp
	* Ajout d'une fonction d'affichage d'une Image à l'écran
	* Ajout d'un objet Commande pour faciliter le transfert entre les fonctions
	* Ajout d'executerCommande()
		* Vérifie si les arguments requis sont présents grâce à argumentPresent()
		* Execute la fonction correspondante dans traitementImage.cpp
	* Ajout de procederCommande() qui gère l'execution d'analyserDecoupe() et d'executerCommande()
* Modifié traitementImage.cpp
	* Puisque chaque fonction n'est pas censé échouer, les types de retour sont des void
	* rectangle() codé
* Modifié affichageFenetre.cpp
	* attendreFenetre() autorise une action sur le clavier
	* Ajout de la valeur globale booléenne fenetreOuverte
	* Corrigé un éventuel bug pouvant arriver lorsque les dimensions étaient rectangulaires
* Modifié l'objet Image
	* Les validateurs sont désormais au nombre de deux, v_pixel() et v_dimensions() pour chaque Image, et sont publics
* Modifié testing.cpp
	* Ajout fonctions génératrices d'images de test pour chaque type de composante
* Mis à jour TODO.md
* Amélioration du Makefile
* Modification de .travis.yml pour placer le `make testing` en post-script
2014-05-08 19:44:09 +02:00
Geoffrey Frogeye 2e5cbafa3c Analyse syntaxique de la commande
Code de la séance du 05/05/14 + Code à la maison
* Différenciation entre flags de production et flags de tests
* Mise à jour de TODO.md
* Abandon de BGI
* Définition partielle de l'analyse de commande
* Ajout de la fonction decoupeCommande()
* Ajout de la fonction boucleDeCommandes()
* Modification de l'appel des fichiers externes
* Ajout d'un mode hors-REPL
* Ajout du code correct pour creer()
* Changement de l'indentation de traitementImage.cpp
2014-05-05 21:00:08 +02:00
LuKiLL c65e17bc7b Update fin-séance 05/05/14
Ajout de la fonction redimensionner.
2014-05-05 12:01:42 +02:00
LuKiLL 1bdea35e4f Update 3/4-séance 05/05/2014
Ajout des fonctions copier, import, trait et rectangle.
MàJ de la liste des fonctions.
2014-05-05 11:29:04 +02:00
Geoffrey Frogeye f237beee15 Instructions pour Travis CI
* Ajout de .travis.yml
* Modification de l'instruction test en testing (ne fait pas la même chose que les test habituels)
* Ajout d'une image par défaut dans test.cpp
* Corrections d'erreurs qui empêchaient la compilation
2014-05-03 19:57:33 +02:00
Geoffrey Frogeye 22bcfb2b2f Mise en fonction de l'objet Image
Import du code de Geoffrey lors de la séance du 14/02/14, la plupart étant du travail à la maison
* Ajout d'un Makefile
	* Seul l'objet image a été découpé
	* Instruction test
* Modification de l'objet Image
	* Initialisation du tableau dans le constructeur
	* Changement de certains int en unsigned int (puisque ne pouvant pas avoir de valeurs négative)
	* typeComposantes est maintenant un ensemble de constantes
	* Correction de diverses fautes
	* Ajout de g_pixelVide pour créer un objet Pixel déjà compatible avec une image
* Modification de test_affichageFenetre.cpp en test.cpp
	* Vérifie désormais si l'objet Image est fonctionnel
* Changement de la façon dont la surface est bloquée dans affichageFenetreSDL.cpp
* Passage de tous les fichiers C++ au formatteur (d'où le nombre exageré de lignes modifiées)
* Correction de README.md
	* Syntaxe
	* Message de mise en garde sur la non-disponibilité d'un fichier binaire
* Mise à jour de TODO.md
* Correction de LICENCE.md
	* Respect de l'ordre alphabétique, et de la cohérence vis-à-vis des autres fichiers
* Ajout des dossiers bin/ et obj/ pour éviter de les créer après un clone
2014-04-28 15:01:14 +02:00
28 changed files with 2103 additions and 426 deletions

15
.gitattributes vendored
View file

@ -12,11 +12,16 @@
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
# Personalisé
*.pbm binary
*.pgm binary
*.ppm binary

3
.gitignore vendored
View file

@ -1,3 +1,2 @@
compile*
bin/*
*.sublime-*
PILG-log.txt

8
.travis.yml Normal file
View file

@ -0,0 +1,8 @@
language: cpp
compiler: gcc
before_install:
- sudo apt-get update
- sudo apt-get install -y libsdl1.2-dev
script: make
after_install:
- make testing

View file

@ -1 +1 @@
*Copyright 2014 Geoffrey et Lucas*
*Copyright 2014 Lucas et Geoffrey*

37
Makefile Normal file
View file

@ -0,0 +1,37 @@
# Variables
## Pour make
.PHONY: clean, mrproper
## Compilation
CXX = g++
CXXFLAGS = -lSDL -lSDLmain
CXXFLAGSDEBUG = -lSDL -lSDLmain -DDEBUG
## Chemins
EXEPATH = bin/
OBJPATH = obj/
SRCPATH = src/
# Programmes possibles
main: $(EXEPATH)main
testing: $(EXEPATH)testing
# Éxecutables
$(EXEPATH)main: $(OBJPATH)main.o $(OBJPATH)image.o
$(CXX) $^ -o $@ $(CXXFLAGS)
$(EXEPATH)testing: $(OBJPATH)testing.o $(OBJPATH)image.o
$(CXX) $^ -o $@ $(CXXFLAGSDEBUG)
# Dépendances
## Fichiers executables
$(OBJPATH)main.o: $(SRCPATH)main.cpp $(SRCPATH)affichageFenetre.cpp $(SRCPATH)image.cpp $(SRCPATH)utilitaires.cpp $(SRCPATH)traitementImage.cpp $(SRCPATH)analyserCommande.cpp
$(CXX) -c $< -o $@ $(CXXFLAGS)
$(OBJPATH)testing.o: $(SRCPATH)testing.cpp $(SRCPATH)affichageFenetre.cpp $(SRCPATH)image.cpp $(SRCPATH)utilitaires.cpp $(SRCPATH)traitementImage.cpp $(SRCPATH)analyserCommande.cpp
$(CXX) -c $< -o $@ $(CXXFLAGSDEBUG)
## Bibliothèques
$(OBJPATH)image.o: $(SRCPATH)image.cpp
$(CXX) -c $< -o $@
# Meta
clean:
rm -rf $(OBJPATH)*.o

37
Makefile.win Normal file
View file

@ -0,0 +1,37 @@
# Variables
## Pour make
.PHONY: clean, mrproper
## Compilation
CXX = g++
CXXFLAGS = -lmingw32 -lSDLmain -lSDL -static-libgcc -static-libstdc++
CXXFLAGSDEBUG = -lmingw32 -lSDLmain -lSDL -static-libgcc -static-libstdc++ -DDEBUG
## Chemins
EXEPATH = bin/
OBJPATH = obj/
SRCPATH = src/
# Programmes possibles
main: $(EXEPATH)main
testing: $(EXEPATH)testing
# Éxecutables
$(EXEPATH)main: $(OBJPATH)main.o $(OBJPATH)image.o
$(CXX) $^ -o $@ $(CXXFLAGS)
$(EXEPATH)testing: $(OBJPATH)testing.o $(OBJPATH)image.o
$(CXX) $^ -o $@ $(CXXFLAGSDEBU2)
# Dépendances
## Fichiers executables
$(OBJPATH)main.o: $(SRCPATH)main.cpp $(SRCPATH)affichageFenetre.cpp $(SRCPATH)image.cpp $(SRCPATH)utilitaires.cpp $(SRCPATH)traitementImage.cpp $(SRCPATH)analyserCommande.cpp
$(CXX) -c $< -o $@ $(CXXFLAGS)
$(OBJPATH)testing.o: $(SRCPATH)testing.cpp $(SRCPATH)affichageFenetre.cpp $(SRCPATH)image.cpp $(SRCPATH)utilitaires.cpp $(SRCPATH)traitementImage.cpp $(SRCPATH)analyserCommande.cpp
$(CXX) -c $< -o $@ $(CXXFLAGSDEBUG)
## Bibliothèques
$(OBJPATH)image.o: $(SRCPATH)image.cpp
$(CXX) -c $< -o $@
# Meta
clean:
rm -rf $(OBJPATH)*.o

View file

@ -1,34 +1,38 @@
#Projet d'ISN de Lucas et Geoffrey
##À propos...
##À propos
###De ce dépôt
###Le dépôt
Ce dépôt a été crée pour faciliter le développement du projet. Son caractère public n'est que lié aux nécessité de GitHub. Si vous ne savez pas de quel projet il s'agit, vous perdez votre temps ici. L'absence de licence (du moins jusqu'aux épreuves) vous interdit de distribuer ou de réutiliser le code, qui de toute façon ne vous aurait pas été utile.
###De ce projet
###Le projet
Ceci est la création de Lucas et de Geoffrey pour l'option Informatique et Sciences du Numérique qui sera présenté lors du Baccalauréat 2013/2014.
Nos noms complets et le nom du lycée sont masqués pour des raisons d'intimité. Les personnes devant nous reconnaître nous reconnaîtront.
###Du programme
###Le programme
Ce programme est un éditeur basique d'images [PBM/PGM/PPM](http://fr.wikipedia.org/wiki/Portable_pixmap) sexécutant en ligne de commande.
*Statut :* Prétotype
*Version :* v1.0.1
*Status :* [![Build Status](https://travis-ci.org/GeoffreyFrogeye/PILG.svg?branch=master)](https://travis-ci.org/GeoffreyFrogeye/PILG)
##Compilation
Il n'existe pas de fichier binaire à télécharger pour le moment, le seul moyen d'avoir un aperçu du programme est de le compiler.
Téléchargement : ```git clone https://github.com/GeoffreyFrogeye/PILG.git```
###Windows
1. Télécharger et installer [MinGW](http://www.mingw.org/)
2. Inclure **MinGW** dans la variable d'environnement ```%PATH%``` : ```set path=%path%;C:\MinGW\bin```
3. Créer le dossier *bin* à la racine du dépôt : ```mkdir bin```
4. Télécharger la [bibliothèque de développement SDL 1.2.15](http://www.libsdl.org/release/SDL-devel-1.2.15-mingw32.tar.gz), copier le contenu des dossier *lib* et *include* de l'archive téléchargée dans le dossier de **MinGW**
5. Télécharger la [bibliothèque dexécution de SDL 1.2.15](http://www.libsdl.org/release/SDL-1.2.15-win32.zip) et placer *SDL.dll* dans le dossier *bin*
6. Compiler : ```g++ src/main.cpp -o bin/main.exe -lmingw32 -lSDLmain -lSDL -static-libgcc -static-libstdc++```
3. Télécharger la [bibliothèque de développement SDL 1.2.15](http://www.libsdl.org/release/SDL-devel-1.2.15-mingw32.tar.gz), copier le contenu des dossier *lib* et *include* de l'archive téléchargée dans le dossier de **MinGW**
4. Télécharger la [bibliothèque dexécution de SDL 1.2.15](http://www.libsdl.org/release/SDL-1.2.15-win32.zip) et placer *SDL.dll* dans le dossier *bin*
5. Compiler : ```mingw32-make -f Makefile.win```
Lexécutable se trouvera dans le dossier *bin*
###Linux
1. Installer la **bibliothèque de développement SDL 1.2** : ```sudo apt-get install libsdl1.2-dev```
2. Créer le dossier *bin* à la racine du dépôt : ```mkdir bin```
3. Compiler : ```g++ src/main.cpp -o bin/main -lSDLmain -lSDL```
###Debian / Linux
1. Installer le nécessaire à la compilation ainsi que la **bibliothèque de développement SDL 1.2** : ```sudo apt-get install build-essential libsdl1.2-dev```
2. Compiler : ```make```
Lexécutable se trouvera dans le dossier *bin*

86
TODO.md
View file

@ -1,53 +1,55 @@
réaliser
####Légende
###Légende
* **D** Définition réalisée
* **A** Algorithme réalisé
* **C** Code réalisé
####Liste générale
###Liste générale
*Ordre donné à titre indicatif*
* Fonction principale
* Fonction d'analyse de commande
* Analyse de la commande
* Analyse des arguments
* Correspondance commandes ↔ fonctions
* Objets
* Fenêtre **D**
* SDL **C**
* BGI **A**
* Fonction principale **C**
* Fonction d'analyse de commande **C**
* Analyse de la commande **C**
* Analyse des arguments **C**
* Execution des fonctions **C**
* Objets **C**
* Fenêtre **C**
* Pixel **C**
* Image **D**
* Image **C**
* Fonctions **D**
* Gestion de fichier
* Créer
* Ouvrir
* Enregistrer
* Importer
* Édition
* Copier tout
* Couper tout
* Coller tout
* Annuler
* Refaire
* Couleur
* Teinte
* Saturation
* Luminosité
* Contraste
* Dessin
* Trait
* Rectangle
* Cercle
* Disque
* Géométrie
* Zoom
* Pivot
* Redimensionner
* Conversion du mode
* Binaire
* Niveaux de gris
* Couleur
* Aide
* Gestion de fichier **A**
* Créer **C**
* Ouvrir **C**
* Enregistrer **C**
* Importer **A**
* Édition
* Copier tout
* Couper tout
* Coller tout
* Annuler
* Refaire
* Couleur **D**
* Teinte **C**
* Saturation **C**
* Luminosité **C**
* Contraste
* Dessin **C**
* Trait **C**
* Rectangle **C**
* Cercle **C**
* Disque **C**
* Géométrie **D**
* Zoomer
* Pivoter **C**
* Retourner **C**
* Redimensionner **C**
* Conversion du mode **C**
* Binaire **C**
* Niveaux de gris **C**
* Couleur **C**
* Documentation
----------
*Copyright 2014 Lucas et Geoffrey*

3
bin/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
# Pour forcer l'ajout de ce dossier dans le dépôt
*
!.gitignore

3
obj/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
# Pour forcer l'ajout de ce dossier dans le dépôt
*
!.gitignore

109
src/affichageFenetre.cpp Normal file
View file

@ -0,0 +1,109 @@
#include <SDL/SDL.h>
#include <string>
int fenetreDimensionX; // Stocke les dimensions X de la fenêtre
int fenetreDimensionY; // Stocke les dimensions Y de la fenêtre
int ecranX = 1024;
int ecranY = 1080;
bool fenetreOuverte = false;
SDL_Surface *fenetreEcran;
SDL_Surface *fenetreImage;
void definirPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) {
int nbOctetsParPixel = surface->format->BytesPerPixel;
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * nbOctetsParPixel;
switch (nbOctetsParPixel) {
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
void s_nomFenetre(std::string nom) { // Change le nom de la fenêtre
SDL_WM_SetCaption(nom.c_str(), NULL);
}
void pointFenetre(int x, int y, int r, int v, int b) {
// std::cout << "(" << x << ";" << y << ") = (" << r << ";" << v << ";" << b << ")" << std::endl; // DEBUG
Uint32 pixel;
Uint8 u_r, u_v, u_b, u_a;
u_r = (r > 255 ? 0xff : (Uint8) r);
u_v = (v > 255 ? 0xff : (Uint8) v);
u_b = (b > 255 ? 0xff : (Uint8) b);
u_a = 0xff;
pixel = SDL_MapRGBA(fenetreImage->format, u_r, u_v, u_b, u_a);
definirPixel(fenetreImage, x, y, pixel);
}
void afficherFenetre() {
SDL_Rect position;
position.x = 0;
position.y = 0;
SDL_UnlockSurface(fenetreImage);
SDL_BlitSurface(fenetreImage, NULL, fenetreEcran, &position);
SDL_Flip(fenetreEcran);
SDL_LockSurface(fenetreImage);
}
void attendreFenetre() {
SDL_Event evenement;
do {
SDL_WaitEvent(&evenement);
} while (evenement.type != SDL_QUIT &&
evenement.type != SDL_KEYDOWN); //|| evenement.type != SDL_KEYDOWN);
}
void fermerFenetre() {
SDL_UnlockSurface(fenetreImage);
SDL_FreeSurface(fenetreImage);
SDL_Quit();
fenetreOuverte = false;
}
void ouvrirFenetre(int dimensionX, int dimensionY,
std::string nom) { // Crée une fenêtre
SDL_Init(SDL_INIT_VIDEO);
fenetreDimensionX = dimensionX;
fenetreDimensionY = dimensionY;
fenetreEcran = SDL_SetVideoMode(fenetreDimensionX, fenetreDimensionY, 32,
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));
s_nomFenetre(nom);
SDL_LockSurface(fenetreImage);
fenetreOuverte = true;
}
void actualiserDimensionsEcran() {
SDL_Init(SDL_INIT_VIDEO);
const SDL_VideoInfo *info = SDL_GetVideoInfo();
ecranX = info->current_w;
ecranY = info->current_h;
SDL_Quit();
}

View file

@ -1,30 +0,0 @@
#include <graphics.h>
int ouvrirFenetre(int dimensionX, int dimensionY, const char* nom) { // Crée une fenêtre
initwindow(dimensionX, dimensionY, nom, 0, 0);
return 0;
}
int setNomFenetre(const char* nom) { // Change le nom de la fenêtre
return 0;
}
int pointFenetre(int x, int y, int r, int v, int b) {
putpixel(x, y, COLOR(r, v, b));
return 0;
}
int afficherFenetre() {
return 0;
}
int attendreFenetre() {
while (kbhit()) {
delay(100);
}
}
int fermerFenetre() {
closegraph(ALL_WINDOWS);
}

View file

@ -1,112 +0,0 @@
#include <SDL/SDL.h>
#include <string>
int fenetreDimensionX; // Stocke les dimensions X de la fenêtre
int fenetreDimensionY; // Stocke les dimensions Y de la fenêtre
SDL_Surface* fenetreEcran;
SDL_Surface* fenetreImage;
void definirPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
/*nbOctetsParPixel représente le nombre d'octets utilisés pour stocker un pixel.
En multipliant ce nombre d'octets par 8 (un octet = 8 bits), on obtient la profondeur de couleur
de l'image : 8, 16, 24 ou 32 bits.*/
int nbOctetsParPixel = surface->format->BytesPerPixel;
/*Ici p est l'adresse du pixel que l'on veut modifier*/
/*surface->pixels contient l'adresse du premier pixel de l'image*/
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * nbOctetsParPixel;
/*Gestion différente suivant le nombre d'octets par pixel de l'image*/
switch(nbOctetsParPixel)
{
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
/*Suivant l'architecture de la machine*/
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
{
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
}
else
{
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
int ouvrirFenetre(int dimensionX, int dimensionY, std::string nom) { // Crée une fenêtre
SDL_Init(SDL_INIT_VIDEO);
fenetreDimensionX = dimensionX;
fenetreDimensionY = dimensionY;
fenetreEcran = SDL_SetVideoMode(fenetreDimensionX, fenetreDimensionY, 32, SDL_HWSURFACE);
fenetreImage = SDL_CreateRGBSurface(SDL_HWSURFACE, fenetreDimensionX, fenetreDimensionX, 32, 0, 0, 0, 0);
SDL_FillRect(fenetreImage, NULL, SDL_MapRGB(fenetreEcran->format, 0, 0, 0));
setNomFenetre(nom);
return 0;
}
int setNomFenetre(std::string nom) { // Change le nom de la fenêtre
SDL_WM_SetCaption(nom.c_str(), NULL);
return 0;
}
int pointFenetre(int x, int y, int r, int v, int b) {
// TODO (erreur) Vérifications des dimensions
// std::cout << "(" << x << ";" << y << ") = (" << r << ";" << v << ";" << b << ")" << std::endl; // DEBUG
Uint32 pixel;
Uint8 u_r, u_v, u_b, u_a;
u_r = (Uint8) (r > 255 ? 255 : r); // TODO (performance, facultatif, erreur) Si > 255, on renvoit 0xff sinon on convertit
u_v = (Uint8) (v > 255 ? 255 : v);
u_b = (Uint8) (b > 255 ? 255 : b);
u_a = (Uint8) 255;
pixel = SDL_MapRGBA(fenetreImage->format, u_r, u_v, u_b, u_a);
SDL_LockSurface(fenetreImage);
definirPixel(fenetreImage, x, y, pixel);
SDL_UnlockSurface(fenetreImage);
return 0;
}
int afficherFenetre() {
// TODO (performance, facultatif) fenetreImage pourrait être crée pendant afficherFenetre(), et pointFenetre() ne modifierait qu'un tableau
SDL_Rect position;
position.x = 0; position.y = 0;
SDL_BlitSurface(fenetreImage, NULL, fenetreEcran, &position);
SDL_Flip(fenetreEcran);
return 0;
}
int attendreFenetre() {
SDL_Event evenement;
while (evenement.type != SDL_QUIT) {
SDL_WaitEvent(&evenement);
}
}
int fermerFenetre() {
SDL_FreeSurface(fenetreImage);
SDL_Quit();
return 0;
}

View file

@ -1,3 +1,570 @@
function analyserCommande(string nom) {
#include <vector>
#include <string>
#include <iostream>
void decoupeCommande(string commande, vector< string > &decoupe) {
// Boucle de découpage
string elementCourrant = "";
bool dansLeVide = false;
bool echape = false;
bool vaEchapper = false;
bool entreSimplesGuillemets = false;
bool entreDoublesGuillemets = false;
for (int i = 0; i < commande.length(); i++) {
echape = false;
if (vaEchapper) {
vaEchapper = false;
echape = true;
}
if (commande[i] == ' ' && !(echape || entreSimplesGuillemets ||
entreDoublesGuillemets)) {
if (!dansLeVide) {
decoupe.push_back(elementCourrant);
elementCourrant = "";
dansLeVide = true;
}
} else if (commande[i] == '\\' && !echape) {
vaEchapper = true;
} else if (commande[i] == '\'' && !(echape || entreDoublesGuillemets)) {
if (entreSimplesGuillemets) {
entreSimplesGuillemets = false;
decoupe.push_back(elementCourrant);
elementCourrant = "";
dansLeVide = true;
} else {
entreSimplesGuillemets = true;
}
} else if (commande[i] == '"' && !(echape || entreSimplesGuillemets)) {
if (entreDoublesGuillemets) {
entreDoublesGuillemets = false;
decoupe.push_back(elementCourrant);
elementCourrant = "";
dansLeVide = true;
} else {
entreDoublesGuillemets = true;
}
} else {
elementCourrant += commande[i];
dansLeVide = false;
}
}
if (!dansLeVide) {
decoupe.push_back(elementCourrant);
}
}
typedef struct Commande {
string fonction;
int x1, x2, y1, y2;
float v1;
bool b1;
string t1;
string fichier, entree, sortie;
Pixel couleur;
PILG_Comp composante;
vector< string > argumentsPresents;
} Commande;
int analyserDecoupe(Commande &commande, vector< string > decoupe,
Image const &image) {
// for (int i = 0; i < decoupe.size(); i++) { // DEBUG
// cout << "Argument " << i << " = " << decoupe[i] << endl;
// }
commande.couleur = image.g_pixelVide();
commande.fonction = decoupe[0];
// // Analyse des arguments
for (int i = 1; i < decoupe.size(); i++) {
if (decoupe[i].at(0) == '-') {
/* */ if (decoupe[i] == "-x1" || decoupe[i] == "-x0" || decoupe[i] == "-x") {
commande.argumentsPresents.push_back("x1");
i++;
if (chaineVersEntier(decoupe[i], commande.x1)) {
return 3;
}
} else if (decoupe[i] == "-y1" || decoupe[i] == "-y0" || decoupe[i] == "-y") {
commande.argumentsPresents.push_back("y1");
i++;
if (chaineVersEntier(decoupe[i], commande.y1)) {
return 3;
}
} else if (decoupe[i] == "-x2" || decoupe[i] == "-X") {
commande.argumentsPresents.push_back("x2");
i++;
if (chaineVersEntier(decoupe[i], commande.x2)) {
return 3;
}
} else if (decoupe[i] == "-y2" || decoupe[i] == "-Y") {
commande.argumentsPresents.push_back("y2");
i++;
if (chaineVersEntier(decoupe[i], commande.y2)) {
return 3;
}
} else if (decoupe[i] == "-v1" || decoupe[i] == "-v" || decoupe[i] == "-a"
|| decoupe[i] == "-r") {
commande.argumentsPresents.push_back("v1");
i++;
if (chaineVersFlottant(decoupe[i], commande.v1)) {
return 3;
}
} else if (decoupe[i] == "-b1" || decoupe[i] == "-b") {
commande.argumentsPresents.push_back("b1");
i++;
if (decoupe[i] == "1" || decoupe[i] == "vrai" || decoupe[i] == "oui") {
commande.b1 = true;
} else if (decoupe[i] == "0" || decoupe[i] == "faux" || decoupe[i] == "non") {
commande.b1 = false;
} else {
return 8;
}
} else if (decoupe[i] == "-t1" || decoupe[i] == "-t") {
commande.argumentsPresents.push_back("t1");
i++;
commande.t1 = decoupe[i];
} else if (decoupe[i] == "-f1" || decoupe[i] == "-f") {
commande.argumentsPresents.push_back("fichier");
i++;
commande.fichier = decoupe[i];
} else if (decoupe[i] == "-e") {
commande.argumentsPresents.push_back("entree");
i++;
commande.entree = decoupe[i];
} else if (decoupe[i] == "-s") {
commande.argumentsPresents.push_back("sortie");
i++;
commande.sortie = decoupe[i];
} else if (decoupe[i] == "-p") {
commande.argumentsPresents.push_back("composante");
i++;
/* */ if (decoupe[i] == "0" || decoupe[i] == "BIN") {
commande.composante = PILG_BIN;
} else if (decoupe[i] == "1" || decoupe[i] == "NIV") {
commande.composante = PILG_NIV;
} else if (decoupe[i] == "2" || decoupe[i] == "RVB") {
commande.composante = PILG_RVB;
} else {
return 10;
}
} else if (decoupe[i] == "-c") {
commande.argumentsPresents.push_back("couleur");
i++;
commande.couleur = image.g_pixelVide();
switch (image.g_typeComposantes()) {
case PILG_BIN:
if (decoupe[i] == "b" || decoupe[i] == "1") {
commande.couleur.n = true;
} else if (decoupe[i] == "n" || decoupe[i] == "0") {
commande.couleur.n = false;
} else {
return 4;
}
break;
case PILG_NIV:
int g;
if (!chaineVersEntier(decoupe[i], g)) {
return 3;
}
if (g > image.g_maxComposante()) {
return 5;
}
commande.couleur.g = g;
break;
case PILG_RVB:
int composante = 0;
string chaineCourante = "";
int entierCourant = 0;
for (int iS = 0; iS <= decoupe[i].length(); iS++) {
if (decoupe[i][iS] == ':' || iS == decoupe[i].length()) {
if (chaineVersEntier(chaineCourante, entierCourant)) {
return 3;
}
if (entierCourant > image.g_maxComposante()) {
return 5;
}
switch (composante) {
case 0:
commande.couleur.r = entierCourant;
break;
case 1:
commande.couleur.v = entierCourant;
break;
case 2:
commande.couleur.b = entierCourant;
break;
default:
return 6;
}
chaineCourante = "";
entierCourant = 0;
composante++;
} else {
chaineCourante += decoupe[i][iS];
}
}
if (composante != 3) {
return 6;
}
break;
}
if (!image.v_pixel(commande.couleur)) {
return 7;
}
} else {
cout << decoupe[i] << endl;
return 2;
}
} else {
return 1;
}
}
journal << endl;
return 0;
}
bool argumentPresent(Commande commande, string argumentVoulu) {
for (int i = 0; i < commande.argumentsPresents.size(); i++) {
if (commande.argumentsPresents[i] == argumentVoulu) {
return true;
}
}
return false;
}
int executerCommande(Commande commande, Image &image) {
if (argumentPresent(commande, "entree")) {
if (ouvrir(image, commande.entree)) {
return 4;
}
}
/* */ if (commande.fonction == "creer") {
if (argumentPresent(commande, "x1") && argumentPresent(commande, "y1")
&& argumentPresent(commande, "v1") && argumentPresent(commande, "composante")) {
if (creer(image, commande.x1, commande.y1, commande.v1, commande.composante)) {
return 3;
}
} else {
return 2;
}
} else if (commande.fonction == "ouvrir") {
if (argumentPresent(commande, "fichier")) {
if (ouvrir(image, commande.fichier)) {
return 3;
}
} else {
return 2;
}
} else if (commande.fonction == "sauver") {
if (argumentPresent(commande, "fichier")) {
if (!argumentPresent(commande, "b1")) {
commande.b1 = false;
}
if (!argumentPresent(commande, "t1")) {
commande.t1 = "Fichier généré par PILG";
}
if (sauver(image, commande.fichier, commande.b1, commande.t1)) {
return 3;
}
} else {
return 2;
}
// } else if (commande.fonction == "importer") {
// if (argumentPresent(commande, "fichier")) {
// if (!argumentPresent(commande, "x1")) {
// commande.x1 = 0;
// }
// if (!argumentPresent(commande, "y1")) {
// commande.y1 = 0;
// }
// if (importer(image, image, commande.fichier,)) {
// return 3;
// }
// } else {
// return 2;
// }
} else if (commande.fonction == "teinte") {
if (image.g_typeComposantes() == PILG_RVB) {
if (argumentPresent(commande, "v1")) {
if (teinte(image, image, commande.v1)) {
return 3;
}
} else {
return 2;
}
} else {
return 11;
}
} else if (commande.fonction == "saturation") {
if (image.g_typeComposantes() == PILG_RVB) {
if (argumentPresent(commande, "v1")) {
if (saturation(image, image, commande.v1)) {
return 3;
}
} else {
return 2;
}
} else {
return 11;
}
} else if (commande.fonction == "luminosite") {
if (image.g_typeComposantes() == PILG_RVB) {
if (argumentPresent(commande, "v1")) {
if (luminosite(image, image, commande.v1)) {
return 3;
}
} else {
return 2;
}
} else {
return 11;
}
// } else if (commande.fonction == "contraste") {
// if (argumentPresent(commande, "v1")) {
// if (contraste(image, image, commande.v1)) {
// return 3;
// }
// } else {
// return 2;
// }
} else if (commande.fonction == "trait") {
if (argumentPresent(commande, "x1") && argumentPresent(commande, "x2")
&& argumentPresent(commande, "y1") && argumentPresent(commande, "y2")
&& argumentPresent(commande, "couleur")) {
if (trait(image, image, commande.x1, commande.y1, commande.x2, commande.y2,
commande.couleur)) {
return 3;
}
} else {
return 2;
}
} else if (commande.fonction == "rectangle") {
if (argumentPresent(commande, "x1") && argumentPresent(commande, "x2")
&& argumentPresent(commande, "y1") && argumentPresent(commande, "y2")
&& argumentPresent(commande, "couleur")) {
if (rectangle(image, image, commande.x1, commande.y1, commande.x2, commande.y2,
commande.couleur)) {
return 3;
}
} else {
return 2;
}
} else if (commande.fonction == "cercle") {
if (argumentPresent(commande, "x1") && argumentPresent(commande, "y1")
&& argumentPresent(commande, "v1") && argumentPresent(commande, "couleur")) {
if (cercle(image, image, commande.x1, commande.y1, commande.v1,
commande.couleur)) {
return 3;
}
} else {
return 2;
}
} else if (commande.fonction == "disque") {
if (argumentPresent(commande, "x1") && argumentPresent(commande, "y1")
&& argumentPresent(commande, "v1") && argumentPresent(commande, "couleur")) {
if (disque(image, image, commande.x1, commande.y1, commande.v1,
commande.couleur)) {
return 3;
}
} else {
return 2;
}
} else if (commande.fonction == "pivoter") {
if (argumentPresent(commande, "x1") && argumentPresent(commande, "y1")
&& argumentPresent(commande, "v1")) {
if (pivoter(image, image, commande.x1, commande.y1, commande.v1)) {
return 3;
}
} else {
return 2;
}
} else if (commande.fonction == "retourner") {
if (argumentPresent(commande, "v1")) {
if (retourner(image, image, commande.v1)) {
return 3;
}
} else {
return 2;
}
} else if (commande.fonction == "redimensionner") {
if (argumentPresent(commande, "x1") && argumentPresent(commande, "x2")
&& argumentPresent(commande, "y1") && argumentPresent(commande, "y2")) {
if (redimensionner(image, image, commande.x1, commande.y1, commande.x2,
commande.y2)) {
return 3;
}
} else {
return 2;
}
} else if (commande.fonction == "convBIN") {
if (convBIN(image, image)) {
return 3;
}
} else if (commande.fonction == "convNIV") {
if (convNIV(image, image)) {
return 3;
}
} else if (commande.fonction == "convRVB") {
if (convRVB(image, image)) {
return 3;
}
} else {
return 1;
}
if (argumentPresent(commande, "sortie")) {
if (sauver(image, commande.sortie, false, "Fichier généré par PILG")) {
return 4;
}
}
return 0;
}
int procederCommande(vector< string > decoupe, Image &image) {
journal << "Commande : ";
for (int i = 0; i < decoupe.size(); i++) {
journal << "«" << decoupe[i] << "» ";
}
Commande commande;
int code;
code = analyserDecoupe(commande, decoupe, image);
switch (code) {
case 0:
code = executerCommande(commande, image);
switch (code) {
case 0:
journal << "Succès" << endl;
break;
case 1:
messageErreur("Fonction inconnue");
break;
case 2:
messageErreur("Arguments manquants");
break;
case 3:
messageErreur("Erreur dans l'execution de la commande");
break;
case 4:
messageErreur("Impossible d'ouvrir l'entrée");
default:
messageErreur("Impossible d'éxecuter la fonction");
break;
}
return code;
case 1:
messageErreur("Un argument a été attendu et autre chose a été donné");
break;
case 2:
messageErreur("Argument inconnu");
break;
case 3:
messageErreur("Un nombre a été attendu et n'a pas été donné");
break;
case 4:
messageErreur("La couleur d'une image binaire doit être blanc (1) ou noir (0)");
break;
case 5:
messageErreur("La valeur d'une composante de couleur donnée est superieure au maximum de composante de l'image");
break;
case 6:
messageErreur("La couleur d'une image RVB possède trois composantes");
break;
case 7:
messageErreur("La couleur donnée n'est pas valide, la raison en est inconnue");
break;
case 8:
messageErreur("Un booléen (vrai/faux) a été attendu mais n'a pas été donné");
break;
case 9:
messageErreur("Une chaine de caractères a été attendue mais n'a pas été donnée");
break;
case 10:
messageErreur("La composante donnée n'est pas valide");
break;
case 11:
messageErreur("Il est nécessaire d'avoir une image en mode RVB pour executer cette commande");
break;
default:
messageErreur("Impossible d'analyser la commande");
break;
}
return code;
}
void boucleDeCommandes(Image image) { // REPL
bool continuer = true;
string commandeTexte;
while (continuer) {
cout << "$ ";
getline(cin, commandeTexte);
if (commandeTexte == "quitter") {
continuer = false;
} else {
vector< string > decoupe;
decoupeCommande(commandeTexte, decoupe);
procederCommande(decoupe, image);
afficherImage(image);
}
}
}

View file

@ -1,55 +1,113 @@
int Image::Image(int dimensionX, int dimensionY, int maxComposante, int typeComposantes) { // Crée l'objet Image
#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) {
Pixel pixelVide = g_pixelVide();
for (int xT = 0; xT < dimensionX; xT++) {
std::vector< Pixel > colonne;
for (int yT = 0; yT < dimensionY; yT++) {
colonne.push_back(pixelVide);
}
m_tab.push_back(colonne);
}
}
// Getters
int Image::g_dimensionX() {
return m_dimensionX;
int Image::g_dimensionX() const {
return m_dimensionX;
}
int Image::g_dimensionY() {
return m_dimensionY;
int Image::g_dimensionY() const {
return m_dimensionY;
}
int Image::g_typeComposante() {
return m_typeComposante;
}
int Image::g_maxComposante() {
return m_typeComposante;
PILG_Comp Image::g_typeComposantes() const {
return m_typeComposantes;
}
int g_point(int x, int y, Pixel &pixel) {
if (en_Limites(x, y)) {
pixel = m_tab[x][y];
return 0;
} else {
return 1;
}
int Image::g_maxComposante() const {
return m_maxComposante;
}
int Image::g_pixel(int x, int y, Pixel &pixel) const {
if (v_dimensions(x, y)) {
pixel = m_tab[x][y];
return 0;
} else {
pixel = g_pixelVide();
return 1;
}
}
// Setters
int Image::s_point(int x, int y, Pixel pixel) {
if (en_Limites(x, y) && pixel.typeComposantes == Image.g_typeComposante && pixel.maxComposante == Image.g_maxComposante && enLimitesComposantes(pixel)) {
m_tab[x][y] = pixel;
}
int Image::s_pixel(int x, int y, Pixel pixel) {
if (v_dimensions(x, y) && v_pixel(pixel)) {
m_tab[x][y] = pixel;
return 0;
} else {
return 1;
}
}
bool Image::enLimitesComposantes(Pixel pixel) {
switch (pixel.typeComposantes) {
case 0:
return true;
break;
case 1:
return pixel.m <= pixel.maxComposante;
break;
case 2:
return (pixel.r <= pixel.maxComposante && pixel.v <= pixel.maxComposante && pixel.b <= pixel.maxComposante);
break;
default:
return false;
break;
}
// Utilitaires
Pixel Image::g_pixelVide() const {
Pixel pixel;
pixel.typeComposantes = m_typeComposantes;
pixel.maxComposante = m_maxComposante;
switch (pixel.typeComposantes) {
case PILG_BIN:
pixel.b = false;
break;
case PILG_NIV:
pixel.g = 0;
break;
case PILG_RVB:
pixel.r = pixel.v = pixel.b = 0;
break;
}
return pixel;
}
bool Image::enLimites(int x, int y) {
return (x >= 0 && x < g_dimensionX && y >= 0 && y < g_dimensionY);
}
Image Image::g_vide() const {
return Image(m_dimensionX, m_dimensionY, m_maxComposante, m_typeComposantes);
}
// Validateurs
bool Image::v_pixel(Pixel pixel) const {
if (pixel.typeComposantes == m_typeComposantes
&& pixel.maxComposante == m_maxComposante) {
switch (pixel.typeComposantes) {
case PILG_BIN:
return true;
break;
case PILG_NIV:
return (pixel.g <= pixel.maxComposante);
break;
case PILG_RVB:
return (pixel.r <= pixel.maxComposante
&& pixel.v <= pixel.maxComposante
&& pixel.b <= pixel.maxComposante);
break;
default:
return false;
break;
}
} else {
return false;
}
}
bool Image::v_dimensions(int x, int y) const {
return (x >= 0 && x < m_dimensionX && y >= 0 && y < m_dimensionY);
}

View file

@ -1,34 +1,41 @@
#include <vector>
typedef Pixel {
int typeComposantes;
int maxComposante;
int r;
int v;
int b;
int g;
bool n;
typedef enum {PILG_BIN, PILG_NIV, PILG_RVB} PILG_Comp;
typedef struct {
PILG_Comp typeComposantes;
int maxComposante;
int r;
int v;
int b;
int g;
bool n;
} Pixel;
class Image {
public:
int Image(int dimensionX, int dimensionY, int maxComposante, int typeComposantes); // Crée l'objet Image
// Getters
int g_dimensionX();
int g_dimensionY();
int g_typeComposante();
int g_maxComposante();
Pixel g_point(int x, int y);
// Setters
int s_point(int x, int y, Pixel pixel);
Image(int dimensionX, int dimensionY, int maxComposante,
PILG_Comp typeComposantes);
// Getters
int g_dimensionX() const;
int g_dimensionY() const;
PILG_Comp g_typeComposantes() const;
int g_maxComposante() const;
int g_pixel(int x, int y, Pixel &pixel) const;
// Setters
int s_pixel(int x, int y, Pixel pixel);
// Utilitaires
Pixel g_pixelVide() const;
Image g_vide() const;
// Validateurs
bool v_pixel(Pixel pixel) const;
bool v_dimensions(int x, int y) const;
private:
bool enLimitesComposantes(Pixel pixel);
bool enLimites(int x, int y);
int m_dimensionX;
int m_dimensionY;
int m_typeComposantes; // 0 : N&B, 1 : Niveaux de gris, 2 : RVB
int m_maxComposante; // Maximum de composante (inutilisé pour binaire)
vector< vector< Pixel > > m_tab;
// Variables
int m_dimensionX;
int m_dimensionY;
PILG_Comp m_typeComposantes;
int m_maxComposante; // Maximum de composante (sauf binaire)
std::vector< std::vector< Pixel > > m_tab;
};

View file

@ -1,23 +1,38 @@
#include <iostream>
#include <string>
#include "affichageFenetreSDL.cpp"
using namespace std;
// Insertion des ensembles de fonctions massives séparés pour plus de clarté
#include "analyserCommande.cpp"
#include "affichageFenetre.cpp"
#include "image.h"
#include "utilitaires.cpp"
#include "traitementImage.cpp"
#include "analyserCommande.cpp"
int main(int argc, char* args[]) {
#if defined(WIN32) // Permet de refaire fonctionner cin et cout sous Windows après démarrage de SDL
freopen("CON", "w", stdout);
freopen("CON", "w", stderr);
#endif
cout << "PILG" << endl; // Message d'entrée et de test
return 0;
int main(int argc, char *args[]) {
#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", stderr);
#endif
presentation();
cout << endl;
Image image = imageDefaut();
int code;
if (argc > 1) { // Si la commande a été entrée avec des arguments
vector< string > decoupe;
for (int i = 1; i < argc; i++) {
decoupe.push_back(args[i]);
}
code = procederCommande(decoupe, image);
} else {
actualiserDimensionsEcran();
afficherImage(image);
boucleDeCommandes(image);
code = 0;
}
journal.close();
return code;
}

View file

@ -1,36 +0,0 @@
#include <iostream>
#include <string>
#include "affichageFenetreBGI.cpp"
using namespace std;
int main(int argc, char* args[]) {
#if defined(WIN32) // Permet de refaire fonctionner cin et cout sous Windows après démarrage de SDL
freopen("CON", "w", stdout);
freopen("CON", "w", stderr);
#endif
cout << "TEST AFFICHAGE FENETRE" << endl; // Message d'entrée et de test
int dimX = 640, dimY = 480;
ouvrirFenetre(dimX, dimY, "Test affichage fenêtre");
for (int c = 0; c <= 255; c++) { // À peu près 58 FPS
for (int x = 0; x <= dimX; x++) {
for (int y = 0; y <= dimY; y++) {
pointFenetre(x, y, c, 255-c, 0);
}
}
afficherFenetre();
}
cout << "Éxecution du programme terminée. Vous pouvez quitter la fenêtre." << endl;
attendreFenetre();
fermerFenetre();
return 0;
}

229
src/testing.cpp Normal file
View file

@ -0,0 +1,229 @@
#include <iostream>
#include <string>
using namespace std;
#include "affichageFenetre.cpp"
#include "image.h"
#include "utilitaires.cpp"
#include "traitementImage.cpp"
#include "analyserCommande.cpp"
#define PI 3.14159265359
Image genererRoue(int dimX, int dimY, int maxComposante) {
Image imageRoue(dimX, dimY, maxComposante, PILG_RVB);
Pixel pointRoue = imageRoue.g_pixelVide();
int x, y, step;
float substep, lum;
for (x = 0; x < dimX; x++) {
for (y = 0; y < dimY; y++) {
step = (x * 6.0) / dimX;
substep = (x - step * (dimX / 6.0)) / (dimX / 6.0) * maxComposante;
lum = 1 - ((float) y) / dimY;
switch (step) {
case 0:
pointRoue.r = maxComposante;
pointRoue.v = substep;
pointRoue.b = 0;
break;
case 1:
pointRoue.r = maxComposante - substep;
pointRoue.v = maxComposante;
pointRoue.b = 0;
break;
case 2:
pointRoue.r = 0;
pointRoue.v = maxComposante;
pointRoue.b = substep;
break;
case 3:
pointRoue.r = 0;
pointRoue.v = maxComposante - substep;
pointRoue.b = maxComposante;
break;
case 4:
pointRoue.r = substep;
pointRoue.v = 0;
pointRoue.b = maxComposante;
break;
case 5:
pointRoue.r = maxComposante;
pointRoue.v = 0;
pointRoue.b = maxComposante - substep;
break;
}
// Dégradé vers le noir
pointRoue.r = pointRoue.r * lum;
pointRoue.v = pointRoue.v * lum;
pointRoue.b = pointRoue.b * lum;
// // Remise dans l'intervalle
// pointRoue.r = (pointRoue.r > maxComposante ? maxComposante : pointRoue.r);
// pointRoue.v = (pointRoue.v > maxComposante ? maxComposante : pointRoue.v);
// pointRoue.b = (pointRoue.b > maxComposante ? maxComposante : pointRoue.b);
if (imageRoue.s_pixel(x, y, pointRoue) == 1) {
journal << "Erreur : s_pixel() a été entré avec des valeurs incorrectes" <<
endl;
journal << "X : " << x << " - Y: " << y << " - R : " << pointRoue.r << " - V : "
<<
pointRoue.v << " - B : " << pointRoue.b << endl;
}
imageRoue.g_pixel(x, y, pointRoue);
}
}
return imageRoue;
}
Image genererDegrade(int dimX, int dimY, int maxComposante) {
Image image(dimX, dimY, maxComposante, PILG_NIV);
Pixel pixel = image.g_pixelVide();
int x, y;
for (x = 0; x < dimX; x++) {
for (y = 0; y < dimY; y++) {
pixel.g = (float) x * maxComposante / dimX;
image.s_pixel(x, y, pixel);
}
}
return image;
}
Image genererBruit(int dimX, int dimY) {
Image image(dimX, dimY, 0, PILG_BIN);
Pixel pixel = image.g_pixelVide();
int x, y;
for (x = 0; x < dimX; x++) {
for (y = 0; y < dimY; y++) {
pixel.n = ((float) rand() / RAND_MAX) < ((float) x / dimX);
image.s_pixel(x, y, pixel);
}
}
return image;
}
int appliquer(Image &image, string nomFichier, bool ASCII) {
ouvrir(image, "tests/" + nomFichier);
Pixel pixel;
image.g_pixel(image.g_dimensionX() / 2, image.g_dimensionY() / 2, pixel);
// teinte(image, image, 180);
// saturation(image, image, 0.3);
// luminosite(image, image, -0.5);
// 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);
attendreFenetre();
}
int main(int argc, char *args[]) {
#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", stderr);
#endif
presentation();
cout << "Éxecution des instructions dans testing.cpp." << endl << endl;
actualiserDimensionsEcran();
#define DIMENSIONS 255
// Image image1 = genererRoue(DIMENSIONS, DIMENSIONS, 255);
Image image1 = imageDefaut();
// Image image = image1.g_vide();
// ouvrir(image1, "tests/PikachuP6.ppm");
// Image image2 = genererRoue(DIMENSIONS * 2, DIMENSIONS, 255);
// afficherImage(image1);
// attendreFenetre();
// Ouvrir fichier
// appliquer(image1, "PikachuP1.pbm", true);
// appliquer(image1, "PikachuP2.pgm", true);
// appliquer(image1, "PikachuP3.ppm", true);
// appliquer(image1, "PikachuP4.pbm", false);
// appliquer(image1, "PikachuP5.pgm", false);
// appliquer(image1, "PikachuP6.ppm", false);
// // Chronomètre
// int tempsDepart = clock();
// journal << "Temps d'execution: " << (float)(clock() - tempsDepart) / 1000000 <<
// "s" << endl;
// // Afficher différentes tailles de fenêtre
// for (int i = 500; i < 1200; i += 10) {
// image1 = genererRoue(i * 2, i, 255);
// afficherImage(image1);
// // attendreFenetre();
// }
// // Roue
// Image image = image1.g_vide();
// for (float i = 0; i < 2 * PI; i += 0.1) {
// pivoter(image1, image, DIMENSIONS/2, DIMENSIONS/2, i);
// afficherImage(image);
// }
// // Roue des couleurs
// for (float i = -1; i <= 1; i += 0.01) {
// teinte(image1, image, i);
// afficherImage(image);
// }
// // Neige en dégradé
// for (int i; i < 300; i++) {
// afficherImage(genererBruit(200, 200));
// }
// Cycle de couleurs avec utilisation d'Image
// Image imageRoue(dimX, dimY, 255, PILG_RVB);
// Pixel pointRoueRoue = imageRoue.g_pixelVide();
// int x, y, c;
// for (c = 0; c < 256; c++) { // À peu près 28 FPS avec SDL
// for (x = 0; x < dimX; x++) {
// for (y = 0; y < dimY; y++) {
// pixel.r = c;
// pixel.v = image.g_maxComposante() - c;
// pixel.b = 0;
// if (image.s_pixel(x, y, pixel) == 1) {
// cerr << "Erreur : s_pixel() a été entré avec des valeurs incorrectes" << endl;
// cout << "X : " << x << " - Y: " << y << " - R : " << pixel.r << " - V : " << pixel.v << " - B : " << pixel.b << endl; // DEBUG
// return 1;
// }
// image.g_pixel(x, y, pixel);
// pointFenetre(x, y, pixel.r, pixel.v, pixel.b);
// }
// }
// afficherFenetre();
// }
// // Cycle de couleurs sans utilisation d'Image
// int x, y, c;
// for (c = 0; c < 256; c++) { // À peu près 75 FPS avec SDL
// for (x = 0; x < dimX; x++) {
// for (y = 0; y < dimY; y++) {
// pointFenetre(x, y, c, 255 - c, 0);
// }
// }
// afficherFenetre();
// }
// cout << "Éxecution du programme terminée. Vous pouvez quitter la fenêtre." << endl;
// fermerFenetre();
journal.close();
return 0;
}

View file

@ -1,145 +1,694 @@
// Gestion de fichiers
int creer(Image &sortie, int dimensionX, int dimensionY, int typeComposante, int maxComposante) { // Créer une image de dimensions X et Y
#include <fstream>
}
int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à partir du nom du fichier
#define PI 3.14159265359
#define MAXCOMPOSANTEDEFAUT 255
#define FICHIER_SEPARATEUR (char) 0x0a
}
int sauver(Image entree, string nomFichier) { // Sauvegarder l'image obtenue dans un nouveau fichier
}
int import(Image entree, Image &sortie, string nomFichier, int x, int y) {
typedef enum {PILG_TYPE, PILG_DIMENSIONS, PILG_MAXCOMPOSANTE, PILG_IMAGE} PILG_OuvrirEtape;
// 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
sortie = *new Image(dimensionX, dimensionY, maxComposante, typeComposantes);
return 0;
}
// Edition
int copier() { // Copie tous les pixels
int ouvrir(Image &sortie,
string nomFichier) { // Ouvrir une image existante à partir du nom du fichier
// Ouverture du fichier
journal << "" << nomFichier << endl;
ifstream streamFichier(nomFichier.c_str(), ios::in);
if (streamFichier) {
// Calcul de la taille (en octets) du fichier
streamFichier.seekg(0, ios::end);
int tailleFichier(streamFichier.tellg());
// Stockage du fichier dans une chaîne
streamFichier.seekg(0, ios::beg);
char *fichier_caracteres = new char [tailleFichier];
streamFichier.read(fichier_caracteres, tailleFichier);
streamFichier.close();
// Variables d'informations
char cara;
PILG_OuvrirEtape ouvrirEtape(PILG_TYPE);
bool ASCII(false);
int dimensionX;
int dimensionY;
int maxComposante;
PILG_Comp typeComposantes;
// Variables de traitement du fichier
string element("");
int x(0);
int y(0);
int i(0);
Pixel pixel;
string tmpASCII;
char RVBcomposante(0); // Composante actuelle pour RVB
for (int c(0); c < tailleFichier; c++) {
cara = fichier_caracteres[c];
if (ouvrirEtape != PILG_IMAGE) {
if (cara == FICHIER_SEPARATEUR) { // En cas de nouvel élément
if (element[0] !=
'#') { // Si c'est un commentaire, on passe à l'élément suivant
switch (ouvrirEtape) {
case PILG_TYPE:
if (element.length() == 2 && element[0] == 'P') {
switch (element[1]) {
case '1':
case '4':
typeComposantes = PILG_BIN;
break;
case '2':
case '5':
typeComposantes = PILG_NIV;
break;
case '3':
case '6':
typeComposantes = PILG_RVB;
break;
default:
return 3;
break;
}
switch (element[1]) {
case '1':
case '2':
case '3':
ASCII = true;
break;
case '4':
case '5':
case '6':
ASCII = false;
break;
default:
return 3;
break;
}
} else {
return 3;
}
ouvrirEtape = PILG_DIMENSIONS;
journal << "Type de fichier : " << element << " (" << ((
typeComposantes == 0) ? "Noir et Blanc" : ((typeComposantes == 1) ?
"Niveaux de gris" : "Rouge / Vert / Bleu")) << ", " << (ASCII ? "ASCII" :
"Brut") << ")" << endl;
break;
case PILG_DIMENSIONS: {
bool espaceDepasse(false);
string dimensionXchaine("");
string dimensionYchaine("");
for (int j(0); j < element.size(); j++) {
if (element[j] == ' ') {
espaceDepasse = true;
} else if (espaceDepasse) {
dimensionYchaine += element[j];
} else {
dimensionXchaine += element[j];
}
}
chaineVersEntier(dimensionXchaine, dimensionX);
chaineVersEntier(dimensionYchaine, dimensionY);
if (!espaceDepasse || dimensionX == 0 || dimensionY == 0) {
return 5;
}
journal << "Dimensions : " << dimensionX << " px / " << dimensionY << "px" <<
endl;
if (typeComposantes == PILG_BIN) {
ouvrirEtape = PILG_IMAGE;
} else {
ouvrirEtape = PILG_MAXCOMPOSANTE;
}
}
break;
case PILG_MAXCOMPOSANTE:
chaineVersEntier(element, maxComposante);
journal << "Maximum de composante" << ((typeComposantes == 2) ? "s" : "") <<
" : "
<< maxComposante << endl;
ouvrirEtape = PILG_IMAGE;
break;
default:
return 4;
break;
}
if (ouvrirEtape == PILG_IMAGE) {
sortie = *new Image(dimensionX, dimensionY, maxComposante, typeComposantes);
pixel = sortie.g_pixelVide();
}
}
element = "";
} else {
element += cara;
}
} else {
if (ASCII) {
if (typeComposantes == PILG_BIN) {
if (cara != FICHIER_SEPARATEUR) {
pixel.n = (cara == 0x31) ? false : true;
sortie.s_pixel(x, y, pixel);
x++;
}
} else {
if (cara == FICHIER_SEPARATEUR) {
if (typeComposantes == PILG_RVB) {
switch (RVBcomposante) {
case 0:
chaineVersEntier(tmpASCII, pixel.r);
RVBcomposante = 1;
break;
case 1:
chaineVersEntier(tmpASCII, pixel.v);
RVBcomposante = 2;
break;
case 2:
chaineVersEntier(tmpASCII, pixel.b);
RVBcomposante = 0;
sortie.s_pixel(x, y, pixel);
x++;
break;
}
} else {
chaineVersEntier(tmpASCII, pixel.g);
sortie.s_pixel(x, y, pixel);
x++;
}
tmpASCII = "";
} else {
tmpASCII += cara;
}
}
} else {
if (typeComposantes == PILG_BIN) {
for (i = 7; i >= 0; i--) {
pixel.n = !((cara >> i) & 0x01);
sortie.s_pixel(x, y, pixel);
x++;
if (x >= dimensionX) {
y++;
x = 0;
}
}
} else {
if (typeComposantes == PILG_RVB) {
switch (RVBcomposante) {
case 0:
pixel.r = caraVersEntier(cara);
RVBcomposante = 1;
break;
case 1:
pixel.v = caraVersEntier(cara);
RVBcomposante = 2;
break;
case 2:
pixel.b = caraVersEntier(cara);
RVBcomposante = 0;
sortie.s_pixel(x, y, pixel);
x++;
break;
}
} else {
pixel.g = caraVersEntier(cara);
sortie.s_pixel(x, y, pixel);
x++;
}
}
}
if (x >= dimensionX) {
y++;
x += -dimensionX;
}
}
}
} else {
journal << "Impossible d'ouvrir le fichier" << endl;
return 1;
}
journal << endl;
return 0;
}
int couper() { // Copie et remplace par du blanc tous les pixels
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);
char numero;
switch (entree.g_typeComposantes()) {
case PILG_BIN:
numero = ASCII ? '1' : '4';
break;
case PILG_NIV:
numero = ASCII ? '2' : '5';
break;
case PILG_RVB:
numero = ASCII ? '3' : '6';
break;
default:
return 1;
}
fichier << "P" << numero << FICHIER_SEPARATEUR;
if (commentaire != "") {
fichier << "# " << commentaire << FICHIER_SEPARATEUR;
}
fichier << entree.g_dimensionX() << " " << entree.g_dimensionY() <<
FICHIER_SEPARATEUR;
if (entree.g_typeComposantes() != PILG_BIN) {
fichier << entree.g_maxComposante() << FICHIER_SEPARATEUR;;
}
Pixel pixel;
char brutBINpixel;
int brutBINpixelRang = 7;
for (int y = 0; y < entree.g_dimensionY(); y++) {
for (int x = 0; x < entree.g_dimensionX(); x++) {
entree.g_pixel(x, y, pixel);
switch (entree.g_typeComposantes()) {
case PILG_BIN:
if (ASCII) {
if (pixel.n) {
fichier << '0';
} else {
fichier << '1';
}
} else {
if (pixel.n) {
brutBINpixel &= ~(1 << brutBINpixelRang);
} else {
brutBINpixel |= 1 << brutBINpixelRang;
}
brutBINpixelRang--;
if (brutBINpixelRang < 0) {
fichier << brutBINpixel;
brutBINpixelRang = 7;
}
}
break;
case PILG_NIV:
if (ASCII) {
fichier << pixel.g << FICHIER_SEPARATEUR;
} else {
fichier << (char) pixel.g;
}
break;
case PILG_RVB:
if (ASCII) {
fichier << pixel.r << FICHIER_SEPARATEUR
<< pixel.v << FICHIER_SEPARATEUR
<< pixel.b << FICHIER_SEPARATEUR;
} else {
fichier << (char) pixel.r
<< (char) pixel.v
<< (char) pixel.b;
}
break;
default:
return 1;
}
}
}
fichier.close();
return 0;
}
int coller() { // Coller les pixels copiés ou coupés.
}
int annuler() { // Annuler la dernière action.
}
int refaire() { // répeter la dernière action
int importer(Image entree, Image &sortie, string nomFichier, int x, int y) {
// Image fichierImporte;
// sortie = entree
// ouvrir(fichierImporte, nomFichier)
// Pour x1 = 0 to x1 = fichierImporte.g_dimensionX
// Pour y1 = 0 to y1 = fichierImporte.g_dimensionY
// sortie.s_pixel(x1 + x, y1 + y, fichierImporte.g_pixel(x1, x2));
// FinPour
// FinPour
return 1;
}
// Couleur
int teinte(Image entree, Image &sortie, float teinte) { // Change la teinte de l'image
// Si la teinte appartient à [0;1[
// r1 = 0
// r2 = 1
// v1 = 1
// v2 = 2
// b1 = 2
// b2 = 0
// Valeur = Teinte
// Sinon Si la teinte appartient à [1;2[
// r1 = 1
// r2 = 2
// v1 = 2
// v2 = 0
// b1 = 0
// b2 = 1
// Valeur = Teinte-1
// Sinon Si la teinte appartient à [2;3]
// r1 = 2
// r2 = 0
// v1 = 0
// v2 = 1
// b1 = 1
// b2 = 2
// Valeur = Teinte-2
// Fin Si
// Pour x=0 à x=image.getDimensionX()
// Pour y=0 à y=image.getDimensionY()
//
//
//
// pixel.r = r1+(r2-r1)*valeur
// pixel.v = v1+(v2-v1)*valeur
// pixel.b = b1+(b2-b1)*valeur
// Fin Pour
// Fin Pour
int teinte(Image entree, Image &sortie,
float teinte) { // Change la teinte de l'image
sortie = entree.g_vide();
Pixel pixel;
TSL tsl;
for (int x = 0; x < sortie.g_dimensionX(); x++) {
for (int y = 0; y < sortie.g_dimensionY(); y++) {
entree.g_pixel(x, y, pixel);
rvb2tsl(pixel, tsl);
tsl.t += teinte;
tsl2rvb(tsl, pixel);
sortie.s_pixel(x, y, pixel);
}
}
return 0;
}
int saturation(Image entree, Image &sortie, float saturation) { // Sature l'image
// Pour x = xMin to x = xMax
// Pour y = yMin to y = yMax
// Ajouter la variable saturation à chaque valeur de chaque pixel
// Ne pas dépasser le seuil limite MaxComposante !!!
// Fin Pour
// Fin Pour
int saturation(Image entree, Image &sortie,
float saturation) { // Sature l'image
sortie = entree.g_vide();
Pixel pixel;
TSL tsl;
for (int x = 0; x < sortie.g_dimensionX(); x++) {
for (int y = 0; y < sortie.g_dimensionY(); y++) {
entree.g_pixel(x, y, pixel);
rvb2tsl(pixel, tsl);
tsl.s *= saturation;
tsl.s = tsl.s > 1 ? 1 : (tsl.s < 0 ? 0 : tsl.s);
tsl2rvb(tsl, pixel);
sortie.s_pixel(x, y, pixel);
}
}
return 0;
}
int luminosite(Image entree, Image &sortie, float luminosite) { // Augmente la luminosité de l'image
// Pour x=0 à x=image.g_DimensionX()
// Pour y=0 à y=image.g_DimensionY()
// si image.g_typeComposante=1
// pixel = image.g_point(x,y);
// pixel.g = luminosite*10+pixel.g;
// image.s_point(x, y, pixel);
// sinon si image.g_typeComposante=2
// pixel = image.g_point(x,y);
// pixel.r = luminosite*10+pixel.r;
// pixel.v = luminosite*10+pixel.v;
// pixel.b = luminosite*10+pixel.b;
// image.s_point(x, y, pixel);
// Fin si
// Fin Pour
// Fin Pour
int luminosite(Image entree, Image &sortie,
float luminosite) { // Augmente la luminosité de l'image
sortie = entree.g_vide();
Pixel pixel;
TSL tsl;
for (int x = 0; x < sortie.g_dimensionX(); x++) {
for (int y = 0; y < sortie.g_dimensionY(); y++) {
entree.g_pixel(x, y, pixel);
rvb2tsl(pixel, tsl);
tsl.l *= luminosite;
tsl.l = tsl.l > 1 ? 1 : (tsl.l < 0 ? 0 : tsl.l);
tsl2rvb(tsl, pixel);
sortie.s_pixel(x, y, pixel);
}
}
return 0;
}
int contraste(Image entree, Image &sortie, float contraste) { // Accentue les contrastes de l'image
// pour x=0 à x=image.g_dimensionX()
//pour y=0 à x=image.g_DimensionY()
//si image.g_typeComposante=1
//pixel = image.g_point(x,y);
//pixel.g = contraste*pixel.g;
// if pixel.g > Image.g_maxComposante
// pixel.g = Image.g_maxComposante
// end if
int contraste(Image entree, Image &sortie,
float contraste) { // Accentue les contrastes de l'image
// À voir
return 1;
}
// Dessin
int trait(Image entree, Image &sortie, int x1, int y1, int x2, int y2, Pixel, pixel) { // 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,
Pixel couleur) { // Dessine un trait d'un point (x1,y1) à un point (x2,y2)
int x;
sortie = entree;
for (x = 0; x <= x2 - x1; x++) {
// cout << "(" << x << ";__) a=" << ((float) x / (x2 - x1)) << " yD=" <<
// (y2 - y1) * ((float)x / (x2 - x1)) << endl;
sortie.s_pixel(x1 + x, y1 + (y2 - y1) * ((float) x / (x2 - x1)), couleur);
}
return 0;
}
int rectangle(Image entree, Image &sortie, int x1, int y1, int x2, int y2) {
int rectangle(Image entree, Image &sortie, int x1, int y1, int x2, int y2,
Pixel couleur) {
sortie = entree;
for (int x = x1; x <= x2; x++) {
for (int y = y1; y <= y2; y++) {
sortie.s_pixel(x, y, couleur);
}
}
return 0;
}
int cercle(Image entree, Image &sortie, int x, int y, int r) {
int cercle(Image entree, Image &sortie, int x0, int y0, int r, Pixel couleur) {
sortie = entree;
for (int x = 0; x <= entree.g_dimensionX(); x++) {
for (int y = 0; y <= entree.g_dimensionY(); y++) {
if ((int) sqrt(pow(x - x0, 2) + pow(y - y0, 2)) == r) {
sortie.s_pixel(x, y, couleur);
}
}
}
return 0;
}
int disque(Image entree, Image &sortie, int x0, int y0, int r, Pixel couleur) {
sortie = entree;
for (int x = 0; x <= entree.g_dimensionX(); x++) {
for (int y = 0; y <= entree.g_dimensionY(); y++) {
if ((int) sqrt(pow(x - x0, 2) + pow(y - y0, 2)) <= r) {
sortie.s_pixel(x, y, couleur);
}
}
}
return 0;
}
// Geométrie
int zoom(Image entree, Image &sortie) {
return 1;
}
int pivoter(Image entree, Image &sortie) {
int pivoter(Image entree, Image &sortie, int x0, int y0, float angle) {
sortie = entree.g_vide();
float xF, yF, angleF, xI, yI, angleI, h;
Pixel pixel = entree.g_pixelVide();
for (xF = 0; xF < entree.g_dimensionX(); xF++) {
for (yF = 0; yF < entree.g_dimensionY(); yF++) {
if (xF == x0 && yF == y0) {
xI = x0;
yI = y0;
} else {
angleF = atan((yF - y0) / (xF - x0));
angleF = (xF - x0 < 0 ? angleF + PI : angleF);
angleI = angleF - angle;
h = sqrt(pow(xF - x0, 2) + pow(yF - y0, 2));
xI = cos(angleI) * h + x0;
yI = sin(angleI) * h + y0;
}
entree.g_pixel((int) xI, (int) yI, 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;
}
int redimensionner(Image entree, Image &sortie) {
int redimensionner(Image entree, Image &sortie, int x1, int y1, int x2,
int y2) {
sortie = *new Image(x2 - x1, y2 - y1, entree.g_maxComposante(),
entree.g_typeComposantes());
Pixel pixel;
for (int x = 0; x <= x2 - x1; x++) {
for (int y = 0; y <= y2 - y1; y++) {
entree.g_pixel(x1 + x, y1 + y, pixel);
sortie.s_pixel(x, y, pixel);
}
}
return 0;
}
// Modification couleur
int convBIN(Image entree, Image &sortie) {
if (entree.g_typeComposantes() == PILG_BIN) {
sortie = entree;
} else {
sortie = *new Image(entree.g_dimensionX(), entree.g_dimensionY(), 0, PILG_BIN);
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_NIV:
pixelF.n = (pixelI.g > (entree.g_maxComposante() / 2));
break;
case PILG_RVB:
pixelF.n = ((pixelI.r + pixelI.v + pixelI.b) / 3 > (entree.g_maxComposante() /
2));
break;
default:
return 2;
}
sortie.s_pixel(x, y, pixelF);
}
}
}
return 0;
}
int convNIV(Image entree, Image &sortie) {
if (entree.g_typeComposantes() == PILG_NIV) {
sortie = entree;
} else {
sortie = *new Image(entree.g_dimensionX(), entree.g_dimensionY(),
MAXCOMPOSANTEDEFAUT, PILG_NIV);
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.g = (pixelI.n ? sortie.g_maxComposante() : 0);
break;
case PILG_RVB:
pixelF.g = (pixelI.r + pixelI.v + pixelI.b) / 3.0 / entree.g_maxComposante() *
sortie.g_maxComposante();
break;
default:
return 1;
}
sortie.s_pixel(x, y, pixelF);
}
}
}
return 0;
}
int convRVB(Image entree, Image &sortie) {
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() {
// Afficher le texte suivant :
return 1;
}

220
src/utilitaires.cpp Normal file
View file

@ -0,0 +1,220 @@
#include <math.h>
#include <fstream>
#define NOMBREOR 1.61803398875
ofstream journal("PILG-log.txt", ios::out | ios::trunc);
void presentation() {
cout << " ____ ___ _ ____ " << endl
<< "| _ \\ |_ _ || | / ___|" << endl
<< "| |_) | | | | | | | _ " << endl
<< "| __/ | | | |___ | |_| |" << endl
<< "|_| |___| |_____| \\____|" << endl;
}
typedef struct {
double t;
double s;
double l;
} TSL;
int rvb2tsl(Pixel entree, TSL &sortie) {
double min, max, r = (float) entree.r / entree.maxComposante,
v = (float) entree.v / entree.maxComposante,
b = (float) entree.b / entree.maxComposante;
min = r < v ? r : v;
min = min < b ? min : b;
max = r > v ? r : v;
max = max > b ? max : b;
sortie.l = (max + min) / 2;
if (max == min) {
sortie.s = 0;
sortie.t = NAN;
} else {
sortie.s = sortie.l < 0.5 ? (max - min) / (max + min) : (max - min) /
(2 - max - min);
}
if (r == max) {
sortie.t = (v - b) / (max - min);
} else if (v == max) {
sortie.t = 2 + (b - r) / (max - min);
} else if (b == max) {
sortie.t = 4 + (r - v) / (max - min);
}
sortie.t *= 60;
if (sortie.t < 0) {
sortie.t += 360;
}
return 0;
}
int tsl2rvb(TSL entree, Pixel &sortie) {
double t3[3], c[3], t2, t1;
while (entree.t < 0.0) {
entree.t += 360.0;
}
while (entree.t > 360.0) {
entree.t += -360.0;
}
if (entree.s == 0) {
fill_n(c, 3, entree.l);
} else {
fill_n(t3, 3, 0);
fill_n(c, 3, 0);
t2 = entree.l < 0.5 ? entree.l * (1 + entree.s) : entree.l + entree.s - entree.l
* entree.s;
t1 = 2 * entree.l - t2;
entree.t /= 360.0;
t3[0] = entree.t + 1 / 3.0;
t3[1] = entree.t;
t3[2] = entree.t - 1 / 3.0;
for (int i = 0; i <= 2; i++) {
if (t3[i] < 0) {
t3[i] += 1;
}
if (t3[i] > 1) {
t3[i] -= 1;
}
if (6 * t3[i] < 1) {
c[i] = t1 + (t2 - t1) * 6 * t3[i];
} else if (2 * t3[i] < 1) {
c[i] = t2;
} else if (3 * t3[i] < 2) {
c[i] = t1 + (t2 - t1) * ((2 / 3.0) - t3[i]) * 6;
} else {
c[i] = t1;
}
}
}
sortie.r = c[0] * sortie.maxComposante;
sortie.v = c[1] * sortie.maxComposante;
sortie.b = c[2] * sortie.maxComposante;
return 0;
}
Image imageDefaut() {
int dimY = 256, dimX = dimY * NOMBREOR, maxComposante = 255;
Image imageRoue(dimX, dimY, maxComposante, PILG_RVB);
int x, y;
TSL tsl;
Pixel pointRoue = imageRoue.g_pixelVide();
tsl.s = 1;
for (x = 0; x < dimX; x++) {
for (y = 0; y < dimY; y++) {
tsl.t = ((float) x / dimX) * 360;
tsl.l = 1 - ((float) y / dimY);
tsl2rvb(tsl, pointRoue);
imageRoue.s_pixel(x, y, pointRoue);
}
}
return imageRoue;
}
void afficherImage(Image image) {
#define MARGE 100
int x, y, r, v, b, eX, eY, echelle, contenableX, contenableY,
dimensionX = image.g_dimensionX(),
dimensionY = image.g_dimensionY(),
typeComposantes = image.g_typeComposantes();
float ratio = (255.0 / image.g_maxComposante());
Pixel pixel;
// Calcul de l'échelle
contenableX = (ecranX - MARGE) / dimensionX;
contenableY = (ecranY - MARGE) / dimensionY;
echelle = (contenableX > contenableY ? contenableY : contenableX);
echelle = (echelle > 0 ? echelle : 1);
dimensionX = dimensionX * echelle;
dimensionY = dimensionY * echelle;
// journal << "Fenêtre: Image(" << image.g_dimensionX() << ";" <<
// image.g_dimensionY() << "), Echelle(" << echelle << "), Fenetre(" <<
// dimensionX << ";" << dimensionY << ")" << endl;
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) {
entier = atoi(chaine.c_str());
if (entier == 0 && chaine != "0") {
return 1;
}
return 0;
}
int chaineVersFlottant(string chaine, float &flottant) {
flottant = atof(chaine.c_str());
if (flottant == 0 && chaine != "0") {
return 1;
}
return 0;
}
int caraVersEntier(char cara) {
// int entier = (int) (0 << 8) + cara;
// entier = entier > 0 ? entier : 256+entier;
int i, entier = 0;
for (i = 0; i < 8; i++) {
entier += ((cara >> i) & 0x01) ? pow(2, i) : 0;
}
return entier;
}

3
tests/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
*
!.gitignore
!Pikachu*

BIN
tests/PikachuP1.pbm Normal file

Binary file not shown.

BIN
tests/PikachuP2.pgm Normal file

Binary file not shown.

BIN
tests/PikachuP3.ppm Normal file

Binary file not shown.

BIN
tests/PikachuP4.pbm Normal file

Binary file not shown.

BIN
tests/PikachuP5.pgm Normal file

Binary file not shown.

BIN
tests/PikachuP6.ppm Normal file

Binary file not shown.