Repost mais sans les smileys:
Bon, je t'ai filé deux fichiers
BidimArray.h
et
BidimArrayImp.h
qui te serviront à faire des tableaux bidimensionnels de types de ton choix, des bits, des octets, des RGBA,....
C'est documenté dans le code, et si tu downloades
http://www.stack.nl/~dimitri/doxygen
le logiciel de doc C++ cool, tu pourras générer l'aide html de cette classe.
J'ai écrit cette classe en faisant bon usage de la STL (même si y'a des choses que je changerais aujourd'hui, mais j'insiste pour que tu essayes de piger ce que j'y fais, c'est pas trop dur, et ça t'évitera de buter contre des problèmes comme moi dans le passé.
N'hésite pas à aller voir mon site web
http://janos.boudet.free.fr/
sur le C++. Je le mets à jour régulièrement
/*!
\file BidimArray.h
\date 24/01/2001
\author Janos Boudet
\brief définit les vecteurs bidimensionnels avec une base d'opérateurs associés. Les Images notamment en seront et on pourra aussi faire des transformations en ondelettes avec. Les constructeurs par recopie (en fait ceux de vector<T> doivent se comporter admirablement
*/
#ifndef __BidimArray_hh__
#define __BidimArray_hh__
#ifdef _msvc
#include <vector>
using namespace std;
#else
#include <vector.h>
#endif
/*!
\class BidimArray
\Author Janos Boudet
\brief La classe de vecteur bidimensionnel. Les données sont rangées en x consécutifs
*/
template <class T>
class BidimArray: protected vector<T>
{
protected:
//!largeur
int w;
//! hauteur
int h;
public:
//! constructeur par défaut: Vecteur de 0x0 pixels
BidimArray();
/*!
\brief constructeur d'un vecteur de x*y valeurs
\param x largeur du vecteur à créer
\param y hauteur du vecteur à créer
*/
BidimArray(int x, int y);
/*!
\brief constructeur avec éventuellement conversion de type
\param other le modèle a partir duquel on construit
*/
template <class X>
BidimArray(const BidimArray<X> & other);
/*!
\brief accède à la valeur (x,y)
\param x abscisses de la case à laquelle on veut accéder
\param y ordonnées de la case à laquelle on veut accéder
\return valeur de la case
*/
T & operator()(int x, int y);
/*!
\brief accède à la valeur (x,y) const
\param x abscisses de la case à laquelle on veut accéder
\param y ordonnées de la case à laquelle on veut accéder
\return valeur de la case
*/
const T & operator ()(int x, int y) const;
/*!
\brief accède au ième pixel avec i=x+y*w
\param i pixel auquel on veut accéder
\return valeur du pixel
*/
T & operator[](int i);
/*!
\brief accède au ième pixel avec i=x+y*w const
\param i pixel auquel on veut accéder
\return valeur du pixel
*/
const T & operator[](int i) const;
/*!
\brief lit la largeur
\return la largeur du vecteur
*/
int GetW() const;
/*!
\brief lit la hauteur
\return la hauteur du vecteur
*/
int GetH() const;
/*!
\brief impose une valeur constante à tout le vecteur
\param value la valeur constante à donner à tout le vecteur
*/
void SetConstantValue(const T & value);
/*!
\brief Copie une portion rectangulaire du vecteur
\param x la plus petite abscisse du rectangle à copier
\param y la plus petite ordonnée du rectangle à copier
\param dx largeur du vecteur à copier
\param dy hauteur du vecteur à copier
\return le rectangle copié
*/
BidimArray<T> Copy(int x=0, int y=0, int dx=0, int dy=0) const;
/*!
\brief insère un vecteur dans le vecteur courant
\param other le vecteur à insérer
\param x abscisse de l'insertion
\param y ordonnée de l'insertion
\renvoit l'image courante ainsi modifiée
*/
BidimArray<T> & Paste(const BidimArray<T> & other, int x, int y);
/*!
\brief opérateur ==
\param other vecteur auquel comparer (tous les éléments et la taille)
\return true ou false
*/
bool operator == (const BidimArray<T> & other);
/*!
\brief envoit l'exception length_error correctement formatée en cas de différence de taille
\param other vecteur auquel comparer
*/
void TestSizeMatch(const BidimArray<T> & other) const;
/*!
\brief met le vecteur à une taille de 0x0 (et au passage libère la mémoire)
*/
void Clear();
/*!
\brief redimensionne le vecteur à une nouvelle taille. L'état des données à la sortie doit être considéré comme indéfini
\param x nouvelle largeur
\param y nouvelle hauteur
*/
void BruteResize(int x, int y);
/*!
\brief écrit une ligne dans l'image. NB la ligne doit avoir une longueur égale à w
\param line la ligne à écrire
\param y quelle ligne remplacer
*/
void WriteLine(const vector<T> & line, int y);
/*!
\brief écrit une colonne dans l'image. NB la colonne doit avoir une hauteur égale à h
\param column la colonne à écrire
\param x quelle colonne remplacer
*/
void WriteColumn(const vector<T> & column, int x);
/*!
\brief lit une ligne dans l'image.
\param y quelle ligne lire
\return la ligne lue
*/
vector<T> ReadLine(int y) const;
/*!
\brief lit une colonne dans l'image.
\param x quelle colonne lire
\return la colonne lue
*/
vector<T> ReadColumn(int x) const;
};
#include "BidimArrayImp.h"
#endif //__BidimArray_hh__
***************************
****************************
*****************************
******************************
******************************
/*!
\file BidimArrayImp.h
\Author Janos Boudet
\date 24/01/2001
\brief implémentation du vecteur bidimentionnel
*/
#include "BidimArray.h"
#include <assert.h>
#ifdef _msvc
#include <stdexcept>
#include <strstream>
using namespace std;
#endif
#ifdef _linux
#include <stdexcept>
#include <strstream>
using namespace std;
#endif
#ifdef _sgi
#include <stdexcept.h>
#include <strstream.h>
#endif
#ifdef DEBUG
//#define BIDIM_ARRAY_RANGE_TEST
#endif
template <class T>
BidimArray<T>::BidimArray(): vector<T>(0), w(0), h(0)
{
//nothing
}
template <class T>
BidimArray<T>::BidimArray(int x, int y): w(x), h(y), vector<T>(x*y)
{
if (w<0)
{
strstream errmsg;
errmsg<<"w="<<w<<"<0 for BidimArray constructor BidimArray(int,int)";
throw(out_of_range(errmsg.str()));
}
if (h<0)
{
strstream errmsg;
errmsg<<"h="<<h<<"<0 for BidimArray constructor BidimArray(int,int)";
throw(out_of_range(errmsg.str()));
}
//on voit bien que l'on aura pas les deux
}
#ifdef _msvc
template <class X, class T>
#else
template <class T>
template <class X>
#endif
BidimArray<T>::BidimArray(const BidimArray<X> & other): w(other.GetW()), h(other.GetH())
{
for (int i=0; i<w*h; i++)
operator[](i)=other[i];
}
/*
NB: il faudrait remplacer tous les strstream par des stringstreams, mais un comportement
bizarre de la STL qui m'interdit ente autres d'inclure les fichiers .h sans le .h et de taper
-LANG:std dans les options de compilation, m'oblige à prendre des strstreams, moins propres
plutôt que des stringstreams.
lors du portage il serait propre de régler cela
*/
template <class T>
inline T & BidimArray<T>::operator()(int x, int y)
{
#ifdef BIDIM_ARRAY_RANGE_TEST
if (x<0)
{
strstream errmsg;
errmsg<<"x="<<x<<"<0 for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (x>=w)
{
strstream errmsg;
errmsg<<"x="<<x<<">=width="<<w<<" for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (y<0)
{
strstream errmsg;
errmsg<<"y="<<y<<"<0 for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (y>=h)
{
strstream errmsg;
errmsg<<"y="<<y<<">=height="<<h<<" for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
#endif
return operator[](x+w*y);
}
template <class T>
inline const T & BidimArray<T>::operator()(int x, int y) const
{
#ifdef BIDIM_ARRAY_RANGE_TEST
if (x<0)
{
strstream errmsg;
errmsg<<"x="<<x<<"<0 for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (x>=w)
{
strstream errmsg;
errmsg<<"x="<<x<<">=width="<<w<<" for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (y<0)
{
strstream errmsg;
errmsg<<"y="<<y<<"<0 for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
if (y>=h)
{
strstream errmsg;
errmsg<<"y="<<y<<">=height="<<h<<" for BidimArray operator()";
throw(out_of_range(errmsg.str()));
}
#endif
return operator[](x+w*y);
}
template <class T>
inline T & BidimArray<T>::operator[](int i)
{
#ifdef BIDIM_ARRAY_RANGE_TEST
if (i<0)
{
strstream errmsg;
errmsg<<"i="<<i<<"<0 for BidimArray operator[]";
throw(out_of_range(errmsg.str()));
}
if (i>=w*h)
{
strstream errmsg;
errmsg<<"i="<<i<<">=width*height="<<w*h<<" for BidimArray operator[]";
throw(out_of_range(errmsg.str()));
}
#endif
return vector<T>::operator[](i);
}
template <class T>
inline const T & BidimArray<T>::operator[](int i) const
{
#ifdef BIDIM_ARRAY_RANGE_TEST
if (i<0)
{
strstream errmsg;
errmsg<<"i="<<i<<"<0 for BidimArray operator[]";
throw(out_of_range(errmsg.str()));
}
if (i>=w*h)
{
strstream errmsg;
errmsg<<"i="<<i<<">=width*height="<<w*h<<" for BidimArray operator[]";
throw(out_of_range(errmsg.str()));
}
#endif
return vector<T>::operator[](i);
}
template <class T>
inline int BidimArray<T>::GetW() const
{
return w;
}
template <class T>
inline int BidimArray<T>::GetH() const
{
return h;
}
template <class T>
void BidimArray<T>::SetConstantValue(const T & value)
{
fill(begin(), end(), value);
}
template <class T>
BidimArray<T> BidimArray<T>::Copy(int x, int y, int dx, int dy) const
{
assert(x>0);
assert(y>0);
assert(dx>0);
assert(dy>0);
assert(x+dx<=w);
assert(y+dy<=h);
//test
//if(x<0)
// throw(out_of_range((stringstream("x out of range : " )<<x<<"!E["<<0<<", "<<w<<"]);
BidimArray<T> newimage(dx,dy);
for (int j=0; j<dy; j++)
for (int i=0; i<dx; i++)
newimage(i,j)=operator()(i+x, j+y);
return newimage;
}
template <class T>
BidimArray<T> & BidimArray<T>::Paste(const BidimArray<T> & other, int x, int y)
{
assert(x>0);
assert(y>0);
assert(x+other.w<=w);
assert(y+other.h<=h);
for (int j=0; j<other.h; j++)
for (int i=0; i<other.w; i++)
operator()(i+x,j+y)=other(i,j);
return *this;
}
template <class T>
bool BidimArray<T>::operator == (const BidimArray<T> & other)
{
if (w!=other.w)
return false;
//if (h!=other.h)
//return false //on ne le fait pas car c'est redondant avec le test suivant
return vector<T>::operator==(other);
}
template <class T>
inline void BidimArray<T>::TestSizeMatch(const BidimArray<T> & other) const
{
if (w!=other.w || h!=other.h)
{
strstream s; //mettre stringstream quand ça bugge pas
s<<"Size mismatch : "<<w<<"x"<<h<<"!="<<other.w<<"x"<<other.h<<
endl;
throw(length_error(s.str()));
}
}
template <class T>
void BidimArray<T>::Clear()
{
BruteResize(0,0);
}
template <class T>
void BidimArray<T>::BruteResize(int x, int y)
{
w=x;
h=y;
resize(x*y);
}
template <class T>
void BidimArray<T>::WriteLine(const vector<T> & line, int y)
{
int wr=y*w;
for (int i=0; i<w; i++, wr++)
operator[](wr)=line[i];
}
template <class T>
void BidimArray<T>::WriteColumn(const vector<T> & column, int x)
{
int wr=x;
for (int i=0; i<h; i++, wr+=w)
operator[](wr)=column[i];
}
template <class T>
vector<T> BidimArray<T>::ReadLine(int y) const
{
int rd=y*w;
vector<T> line(w);
for (int i=0; i<w; i++, rd++)
line[i]=operator[](rd);
return line;
}
template <class T>
vector<T> BidimArray<T>::ReadColumn(int x) const
{
int rd=x;
vector<T> column(h);
for (int i=0; i<h; i++, rd+=w)
column[i]=operator[](rd);
return column;
}
---------------
-----------------------