This repository has been archived on 2019-08-08. You can view files and clone it, but cannot push or open issues or pull requests.
PILG/src/traitementImage.cpp
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

529 lines
19 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <fstream>
#define PI 3.14159265359
#define MAXCOMPOSANTEDEFAUT 255
#define FICHIER_SEPARATEUR (char) 0x0a
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;
}
int ouvrir(Image &sortie, string nomFichier) { // Ouvrir une image existante à partir du nom du fichier ***Geoffrey
// Ouverture du fichier
#if DEBUG
cout << "" << nomFichier << endl;
#endif
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;
#if DEBUG
cout << "Type de fichier : " << element << " (" << ((typeComposantes == 0) ? "Noir et Blanc" : ((typeComposantes == 1) ? "Niveaux de gris" : "Rouge / Vert / Bleu")) << ", " << (ASCII ? "ASCII" : "Brut") << ")" << endl;
#endif
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;
}
#if DEBUG
cout << "Dimensions : " << dimensionX << " px / " << dimensionY << "px" << endl;
#endif
if (typeComposantes == PILG_BIN) {
ouvrirEtape = PILG_IMAGE;
} else {
ouvrirEtape = PILG_MAXCOMPOSANTE;
}
}
break;
case PILG_MAXCOMPOSANTE:
chaineVersEntier(element, maxComposante);
#if DEBUG
cout << "Maximum de composante" << ((typeComposantes == 2) ? "s" : "") << " : " << maxComposante << endl;
#endif
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 {
return 1;
}
#if DEBUG
cout << endl;
#endif
return 0;
}
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 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
// for (int x = 0, x = image.g_DimensionX(), x++) {
// for (int y = 0, y = image.g_DimensionY(), y++) {
// rvbVersTsl();
// g_pixel(x, y);
// }
// }
// return 1;
}
int saturation(Image entree, Image &sortie, float saturation) { // Sature l'image
// Utilisation de la méthode TSL
return 1;
}
int luminosite(Image entree, Image &sortie, float luminosite) { // Augmente la luminosité de l'image
// Utilisation de la méthode TSL
return 1;
}
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 couleur) { // Dessine un trait d'un point (x1,y1) à un point (x2,y2)
// int x, y, dx, dy;
// float e, e(1, 0), e(0, 1) ; // valeur derreur et incréments
// dy = y2 - y1 ;
// dx = x2 - x1 ;
// y = y1 ; // rangée initiale
// e = 0, 0 ; // valeur derreur initiale
// e(1, 0) = dy / dx ;
// e(0, 1) = -1.0 ;
// 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
// 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) {
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 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 (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 (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 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) {
return 1;
}
int redimensionner(Image entree, Image &sortie, int x1, int x2, int y1, int y2) {
sortie = *new Image(x2 - x1, y2 - y1, entree.g_maxComposante(), entree.g_typeComposantes());
Pixel pixel = entree.g_pixelVide();
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);
}
}
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) {
return 1;
}
//Help
int aide() {
//Afficher le texte suivant :
return 1;
}