summaryrefslogtreecommitdiff
path: root/2005/i/robert/src/image
diff options
context:
space:
mode:
authorschodet2005-03-13 20:09:29 +0000
committerschodet2005-03-13 20:09:29 +0000
commit2f7a5c3050668a308d98593979ccd8df8c115bb4 (patch)
tree681a0ec5d8dd6efdbbfd06746053eae9f70e7d6a /2005/i/robert/src/image
parent4b2f35d007639332d30ed561dabd1b1967f50f10 (diff)
Ajout de image.
Diffstat (limited to '2005/i/robert/src/image')
-rw-r--r--2005/i/robert/src/image/Makefile.defs7
-rw-r--r--2005/i/robert/src/image/image.cc146
-rw-r--r--2005/i/robert/src/image/image.hh114
-rw-r--r--2005/i/robert/src/image/image.tcc121
-rw-r--r--2005/i/robert/src/image/image_reader.hh42
-rw-r--r--2005/i/robert/src/image/image_writer.hh42
-rw-r--r--2005/i/robert/src/image/raw_reader.hh44
-rw-r--r--2005/i/robert/src/image/test_image.cc73
8 files changed, 589 insertions, 0 deletions
diff --git a/2005/i/robert/src/image/Makefile.defs b/2005/i/robert/src/image/Makefile.defs
new file mode 100644
index 0000000..1423798
--- /dev/null
+++ b/2005/i/robert/src/image/Makefile.defs
@@ -0,0 +1,7 @@
+PROGRAMS += test_image
+
+image_OBJECTS = image.o
+
+test_image_OBJECTS = test_image.o $(image_OBJECTS)
+
+test_image: $(test_image_OBJECTS)
diff --git a/2005/i/robert/src/image/image.cc b/2005/i/robert/src/image/image.cc
new file mode 100644
index 0000000..99968c9
--- /dev/null
+++ b/2005/i/robert/src/image/image.cc
@@ -0,0 +1,146 @@
+// image.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "image.hh"
+#include "image_reader.hh"
+#include "image_writer.hh"
+
+#include <cstring>
+#include <new>
+
+/// Construit une image vide.
+Image::Image (void)
+ // Évite les tests pour toutes les opérations en fabriquant un Rep vide.
+ : rep_ (Rep::create (0, 0, rgb))
+{
+}
+
+/// Construit une image aux pixels non initialisée.
+Image::Image (int width, int length, Image::PixelFormat pixelFormat)
+ : rep_ (Rep::create (width, length, pixelFormat))
+{
+}
+
+/// Construit une image directement à partir d'un ImageReader.
+Image::Image (ImageReader &reader)
+ : rep_ (0)
+{
+ read (reader);
+}
+
+/// Opérateur d'affectation.
+Image &
+Image::operator= (const Image &rhs)
+{
+ rep_->release ();
+ rep_ = rhs.rep_->copyRef ();
+ return *this;
+}
+
+/// Lit une image.
+void
+Image::read (ImageReader &reader)
+{
+ int width, height;
+ PixelFormat pixelFormat;
+ // Récupère les paramètres.
+ reader.getParam (width, height, pixelFormat);
+ // Réalloue de la mémoire si nécessaire.
+ if (!rep_
+ || rep_->references_ != 0
+ || width != rep_->width_
+ || height != rep_->height_
+ || pixelFormat != rep_->pixelFormat_)
+ {
+ if (rep_)
+ rep_->release ();
+ rep_ = Rep::create (width, height, pixelFormat);
+ }
+ // Charge l'image.
+ reader.read (rep_->getBuf (), getBufSize ());
+}
+
+/// Écrit une image.
+void
+Image::write (ImageWriter &writer) const
+{
+ writer.setParam (rep_->width_, rep_->height_, rep_->pixelFormat_);
+ writer.write (rep_->getBuf (), getBufSize ());
+}
+
+/// Crée un Rep, avec de la place pour l'image.
+Image::Rep *
+Image::Rep::create (int width, int height, Image::PixelFormat pixelFormat)
+{
+ unsigned bpp = Image::getBytePerPixel (pixelFormat);
+ unsigned bufSize = Image::getBufSize (width, height, pixelFormat);
+ void *p = new uint8_t[bufSize * sizeof (uint8_t) + sizeof (Rep)];
+ Rep *rep = new (p) Rep;
+ rep->width_ = width;
+ rep->height_ = height;
+ rep->pixelFormat_ = pixelFormat;
+ rep->bpp_ = bpp;
+ rep->bufSize_ = bufSize;
+ rep->references_ = 0;
+ return rep;
+}
+
+/// Copie un Rep, par référence (ne fait qu'incrémenter le nombre de
+/// références).
+Image::Rep *
+Image::Rep::copyRef (void)
+{
+ references_++;
+ return this;
+}
+
+/// Copie un Rep, vrai copie.
+Image::Rep *
+Image::Rep::copy (void)
+{
+ Rep *rep = Rep::create (width_, height_, pixelFormat_);
+ memcpy (rep->getBuf (), getBuf (), bufSize_);
+ // On peut décrémenter references_ car sa valeur a déjà été testée (sinon
+ // on n'aurait pas été appelé.
+ references_--;
+ return rep;
+}
+
+/// Libère le Rep, detruit si necessaire.
+void
+Image::Rep::release (void)
+{
+ if (references_ == 0)
+ destroy ();
+ else
+ references_--;
+}
+
+/// Détruit le Rep.
+void
+Image::Rep::destroy (void)
+{
+ delete[] reinterpret_cast<uint8_t *> (this);
+}
+
diff --git a/2005/i/robert/src/image/image.hh b/2005/i/robert/src/image/image.hh
new file mode 100644
index 0000000..2496ef7
--- /dev/null
+++ b/2005/i/robert/src/image/image.hh
@@ -0,0 +1,114 @@
+#ifndef image_hh
+#define image_hh
+// image.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+#include <stdint.h>
+
+class ImageReader;
+class ImageWriter;
+
+/// Classe contenant une image. Le but est de faciliter l'échange des images
+/// entre différentes classes, et de minimiser les copies. Il y a un comptage
+/// de référence et un copy-on-write, ce qui veut dire que si l'on copie cet
+/// objet, il n'y a pas de copie des pixels tant que l'on essaye pas de la
+/// modifier.
+///
+/// La classe n'est pas thread-safe à cause du comptage de référence
+/// implémenté sans lock.
+class Image
+{
+ public:
+ enum PixelFormat { rgb, bgr, yuv422, yuv, hsi };
+ typedef uint32_t pixel_t;
+ public:
+ /// Construit une image vide.
+ Image (void);
+ /// Construit une image aux pixels non initialisée.
+ Image (int width, int length, PixelFormat pixelFormat);
+ /// Constructeur de copie, copy-on-write.
+ Image (const Image &image);
+ /// Construit une image directement à partir d'un ImageReader.
+ Image (ImageReader &reader);
+ /// Destructeur.
+ ~Image (void);
+ /// Opérateur d'affectation.
+ Image &operator= (const Image &rhs);
+ /// Récupère la taille de l'image.
+ void getSize (int &width, int &height) const;
+ /// Retourne le format des pixels.
+ PixelFormat getPixelFormat (void) const;
+ /// Retourne le nombre d'octets par pixels.
+ unsigned getBytePerPixel (void) const;
+ /// Retourne le nombre d'octets par pixels pour un format donnée.
+ static unsigned getBytePerPixel (PixelFormat pixelFormat);
+ /// Retourne la taille du tampon mémoire.
+ unsigned getBufSize (void) const;
+ /// Retourne la taille du tampon mémoire pour une image donnée.
+ static unsigned getBufSize (int width, int height, PixelFormat pixelFormat);
+ /// Récupère un pointeur vers l'image.
+ const uint8_t *getBuf (void) const;
+ /// Récupère un pointeur mutable vers l'image. Déclenche éventuellement
+ /// une copie.
+ uint8_t *getMutableBuf (void);
+ /// Lit une image.
+ void read (ImageReader &reader);
+ /// Écrit une image.
+ void write (ImageWriter &writer) const;
+ private:
+ struct Rep
+ {
+ int width_;
+ int height_;
+ PixelFormat pixelFormat_;
+ unsigned bpp_;
+ unsigned bufSize_;
+ int references_;
+ public:
+ /// Crée un Rep, avec de la place pour l'image.
+ static Rep *create (int width, int height, PixelFormat pixelFormat);
+ /// Copie un Rep, par référence (ne fait qu'incrémenter le nombre de
+ /// références).
+ Rep *copyRef (void);
+ /// Copie un Rep, vrai copie.
+ Rep *copy (void);
+ /// Libère le Rep, detruit si necessaire.
+ void release (void);
+ /// Détruit le Rep.
+ void destroy (void);
+ /// Récupère le buffer.
+ uint8_t *getBuf (void);
+ private:
+ /// Constructeur, interdit.
+ Rep (void);
+ /// Constructeur de copie, interdit.
+ Rep (const Rep &rep);
+ };
+ mutable Rep *rep_;
+};
+
+#include "image.tcc"
+
+#endif // image_hh
diff --git a/2005/i/robert/src/image/image.tcc b/2005/i/robert/src/image/image.tcc
new file mode 100644
index 0000000..5baed09
--- /dev/null
+++ b/2005/i/robert/src/image/image.tcc
@@ -0,0 +1,121 @@
+// image.tcc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+
+/// Constructeur de copie, copy-on-write.
+inline
+Image::Image (const Image &image)
+ : rep_ (image.rep_->copyRef ())
+{
+}
+
+/// Destructeur.
+inline
+Image::~Image (void)
+{
+ rep_->release ();
+}
+
+/// Récupère la taille de l'image.
+inline
+void
+Image::getSize (int &width, int &height) const
+{
+ width = rep_->width_;
+ height = rep_->height_;
+}
+
+/// Retourne le format des pixels.
+inline
+Image::PixelFormat
+Image::getPixelFormat (void) const
+{
+ return rep_->pixelFormat_;
+}
+
+/// Retourne le nombre d'octets par pixels.
+inline
+unsigned
+Image::getBytePerPixel (void) const
+{
+ return rep_->bpp_;
+}
+
+/// Retourne le nombre d'octets par pixels pour un format donnée.
+inline
+unsigned
+Image::getBytePerPixel (Image::PixelFormat pixelFormat)
+{
+ return pixelFormat == Image::yuv422 ? 2 : 3;
+}
+
+/// Retourne la taille du tampon mémoire.
+inline
+unsigned
+Image::getBufSize (void) const
+{
+ return rep_->bufSize_;
+}
+
+/// Retourne la taille du tampon mémoire pour une image donnée.
+inline
+unsigned
+Image::getBufSize (int width, int height, Image::PixelFormat pixelFormat)
+{
+ return width * height * Image::getBytePerPixel (pixelFormat);
+}
+
+/// Récupère un pointeur vers l'image.
+inline
+const uint8_t *
+Image::getBuf (void) const
+{
+ return rep_->getBuf ();
+}
+
+/// Récupère un pointeur mutable vers l'image. Déclenche éventuellement
+/// une copie.
+inline
+uint8_t *
+Image::getMutableBuf (void)
+{
+ if (rep_->references_ != 0)
+ rep_ = rep_->copy ();
+ return rep_->getBuf ();
+}
+
+/// Récupère le buffer.
+inline
+uint8_t *
+Image::Rep::getBuf (void)
+{
+ return reinterpret_cast<uint8_t *> (this + 1);
+}
+
+/// Constructeur, interdit.
+inline
+Image::Rep::Rep (void)
+{
+}
+
diff --git a/2005/i/robert/src/image/image_reader.hh b/2005/i/robert/src/image/image_reader.hh
new file mode 100644
index 0000000..fd6d308
--- /dev/null
+++ b/2005/i/robert/src/image/image_reader.hh
@@ -0,0 +1,42 @@
+#ifndef image_reader_hh
+#define image_reader_hh
+// image_reader.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "image.hh"
+
+/// Classe de base d'un lecteur d'image.
+class ImageReader
+{
+ public:
+ /// Destructeur.
+ virtual ~ImageReader (void) { }
+ /// Récupère les paramètres de l'image.
+ virtual void getParam (int &width, int &height,
+ Image::PixelFormat &pixelFormat) const = 0;
+ /// Lit une image, lance une exception en cas d'erreur.
+ virtual void read (uint8_t *buf, unsigned size) = 0;
+};
+
+#endif // image_reader_hh
diff --git a/2005/i/robert/src/image/image_writer.hh b/2005/i/robert/src/image/image_writer.hh
new file mode 100644
index 0000000..eef61b0
--- /dev/null
+++ b/2005/i/robert/src/image/image_writer.hh
@@ -0,0 +1,42 @@
+#ifndef image_writer_hh
+#define image_writer_hh
+// image_writer.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "image.hh"
+
+/// Classe de base d'un écrivain d'image.
+class ImageWriter
+{
+ public:
+ /// Destructeur.
+ virtual ~ImageWriter (void) { }
+ /// Paramètre l'image.
+ virtual void setParam (int with, int height,
+ Image::PixelFormat &pixelFormat) = 0;
+ /// Écrit une image, lance une exception en cas d'erreur.
+ virtual void write (uint8_t *buf, unsigned size) = 0;
+};
+
+#endif // image_writer_hh
diff --git a/2005/i/robert/src/image/raw_reader.hh b/2005/i/robert/src/image/raw_reader.hh
new file mode 100644
index 0000000..8f401f2
--- /dev/null
+++ b/2005/i/robert/src/image/raw_reader.hh
@@ -0,0 +1,44 @@
+#ifndef raw_reader_hh
+#define raw_reader_hh
+// raw_reader.hh
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "image_reader.hh"
+
+/// Classe de lecture d'images crues.
+class RawReader : public ImageReader
+{
+ int width_, height_;
+ Image::PixelFormat pixelFormat_;
+ public:
+ /// Destructeur.
+ ~ImageReader (void) { }
+ /// Récupère les paramètres de l'image.
+ void getParam (int &width, int &height,
+ Image::PixelFormat &pixelFormat) const;
+ /// Lit une image, lance une exception en cas d'erreur.
+ void read (uint8_t *buf, unsigned size);
+};
+
+#endif // raw_reader_hh
diff --git a/2005/i/robert/src/image/test_image.cc b/2005/i/robert/src/image/test_image.cc
new file mode 100644
index 0000000..d8b388e
--- /dev/null
+++ b/2005/i/robert/src/image/test_image.cc
@@ -0,0 +1,73 @@
+// test_image.cc
+// robert - programme du robot 2005. {{{
+//
+// Copyright (C) 2005 Nicolas Schodet
+//
+// Robot APB Team/Efrei 2005.
+// Web: http://assos.efrei.fr/robot/
+// Email: robot AT efrei DOT fr
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "image.hh"
+
+#include <iostream>
+#include <algorithm>
+#include <iterator>
+
+void
+printImage (const char *msg, const Image &i)
+{
+ int w, h, bpp, s;
+ i.getSize (w, h);
+ bpp = i.getBytePerPixel ();
+ s = i.getBufSize ();
+ std::cout << msg << ' ' << w << ' ' << h << ' ' << bpp << ' ' << s <<
+ std::endl;
+ const uint8_t *first = i.getBuf ();
+ const uint8_t *last = i.getBuf () + s;;
+ std::copy (first, last, std::ostream_iterator<uint8_t> (std::cout));
+ std::cout << std::endl;
+}
+
+int
+main (void)
+{
+ try
+ {
+ Image i1 (1, 2, Image::rgb);
+ uint8_t *p = i1.getMutableBuf ();
+ memcpy (p, "rgbRGB", 6);
+ printImage ("i1", i1);
+ Image i2 (i1);
+ printImage ("i2 (i1)", i2);
+ i2 = i1;
+ printImage ("i2 = i1", i2);
+ memcpy (p, "123456", 6);
+ printImage ("i1 (buggy modification)", i1);
+ printImage ("i2", i2);
+ p = i1.getMutableBuf ();
+ memcpy (p, "654321", 6);
+ printImage ("i1 (clean modification)", i1);
+ printImage ("i2", i2);
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << e.what () << std::endl;
+ return 1;
+ }
+ return 0;
+}