
--- milena/ChangeLog | 4 + .../core/image/{image2d.hh => image2d_ffmpeg.hh} | 378 +++++++------------- 2 files changed, 134 insertions(+), 248 deletions(-) copy milena/mln/core/image/{image2d.hh => image2d_ffmpeg.hh} (54%) diff --git a/milena/ChangeLog b/milena/ChangeLog index 1f9c705..9d80632 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,5 +1,9 @@ 2013-04-18 Guillaume Lazzara <z@lrde.epita.fr> + * mln/core/image/image2d_ffmpeg.hh: New image type for ffmpeg frames. + +2013-04-18 Guillaume Lazzara <z@lrde.epita.fr> + Add support for graylevel images in labeling::blobs. * mln/canvas/labeling/blobs.hh: Add a fastest version and make it diff --git a/milena/mln/core/image/image2d.hh b/milena/mln/core/image/image2d_ffmpeg.hh similarity index 54% copy from milena/mln/core/image/image2d.hh copy to milena/mln/core/image/image2d_ffmpeg.hh index 7ef0102..40c2717 100644 --- a/milena/mln/core/image/image2d.hh +++ b/milena/mln/core/image/image2d_ffmpeg.hh @@ -1,5 +1,4 @@ -// Copyright (C) 2007, 2008, 2009, 2011, 2012, 2013 EPITA Research and -// Development Laboratory (LRDE) +// Copyright (C) 2013 EPITA Research and Development Laboratory (LRDE) // // This file is part of Olena. // @@ -24,13 +23,12 @@ // exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. -#ifndef MLN_CORE_IMAGE_IMAGE2D_HH -# define MLN_CORE_IMAGE_IMAGE2D_HH +#ifndef MLN_CORE_IMAGE_IMAGE2D_FFMPEG_HH +# define MLN_CORE_IMAGE_IMAGE2D_FFMPEG_HH /// \file -/// Definition of the basic mln::image2d class. +/// Definition of the basic mln::image2d_ffmpeg class. /// -/// \todo Re-activate include at EOF when make::image2d is up again. # include <mln/core/internal/image_primary.hh> # include <mln/core/internal/fixme.hh> @@ -40,14 +38,6 @@ # include <mln/border/thickness.hh> # include <mln/value/set.hh> # include <mln/fun/i2v/all_to.hh> -// # include <mln/core/line_piter.hh> // FIXME - - - -// FIXME: - -// # include <mln/core/pixter2d.hh> -// # include <mln/core/dpoints_pixter.hh> @@ -56,33 +46,27 @@ namespace mln { // Forward declaration. - template <typename T> class image2d; + template <typename T> class image2d_ffmpeg; namespace internal { /*! - \brief Data structure for \c mln::image2d<T>. + \brief Data structure for \c mln::image2d_ffmpeg<T>. */ template <typename T> - struct data< image2d<T> > + struct data< image2d_ffmpeg<T> > { - data(const box2d& b, unsigned bdr); + data(AVFrame *frame); ~data(); + AVFrame *frame; + T* buffer_; T** array_; box2d b_; // theoretical box - unsigned bdr_; - box2d vb_; // virtual box, i.e., box including the virtual border - - void update_vb_(); - void allocate_(); - void deallocate_(); - void swap_(data< image2d<T> >& other_); - void reallocate_(unsigned new_border); }; } // end of namespace mln::internal @@ -91,11 +75,11 @@ namespace mln { template <typename T> - struct image_< image2d<T> > : default_image_< T, image2d<T> > + struct image_< image2d_ffmpeg<T> > : default_image_< T, image2d_ffmpeg<T> > { // misc typedef trait::image::category::primary category; - typedef trait::image::speed::fastest speed; + typedef trait::image::speed::slow speed; typedef trait::image::size::regular size; // value @@ -113,14 +97,28 @@ namespace mln typedef trait::image::dimension::two_d dimension; // extended domain - typedef trait::image::ext_domain::extendable ext_domain; - typedef trait::image::ext_value::multiple ext_value; - typedef trait::image::ext_io::read_write ext_io; + typedef trait::image::ext_domain::none ext_domain; + typedef trait::image::ext_value::irrelevant ext_value; + typedef trait::image::ext_io::irrelevant ext_io; }; } // end of namespace mln::trait + namespace internal + { + + avformat_helper + + template <typename V> + avformat_helper + { + typedef undefined res; + }; + + } // end of namespace mln::internal + + /// Basic 2D image class. /// @@ -131,9 +129,9 @@ namespace mln /// \ingroup modimageconcrete // template <typename T> - class image2d : public internal::image_primary< T, mln::box2d, image2d<T> > + class image2d_ffmpeg : public internal::image_primary< T, mln::box2d, image2d_ffmpeg<T> > { - typedef internal::image_primary< T, mln::box2d, image2d<T> > super_; + typedef internal::image_primary< T, mln::box2d, image2d_ffmpeg<T> > super_; public: /// Value associated type. @@ -145,26 +143,24 @@ namespace mln /// Return type of read-write access. typedef T& lvalue; + typedef avformat_helper<T>::res format; + /// Skeleton. - typedef image2d< tag::value_<T> > skeleton; + typedef image2d_ffmpeg< tag::value_<T> > skeleton; /// Constructor without argument. - image2d(); + image2d_ffmpeg(); /// Constructor with the numbers of rows and columns and the /// border thickness. - image2d(int nrows, int ncols, unsigned bdr = border::thickness); - - /// Constructor with a box and the border thickness (default is - /// 3). - image2d(const box2d& b, unsigned bdr = border::thickness); + image2d_ffmpeg(AVFrame *frame); /// \cond INTERNAL_API /// Initialize an empty image. - void init_(const box2d& b, unsigned bdr = border::thickness); + void init_(const box2d& b); /// \endcond @@ -186,27 +182,6 @@ namespace mln /// Read-write access to the image value located at point \p p. T& operator()(const point2d& p); - - template <typename P> - T& alt(const P& p) - { - typedef def::coord coord_t; - mln_precondition(this->has(p)); - -// std::cout << (coord_t*)(&p.p_hook_()) << ' ' -// << &(p.row()) << ' ' -// << &(p.get_subject()) << ' ' -// << &(p.to_site()) << std::endl; - - // return this->data_->array_[p.to_site().row()][p.to_site().col()]; - // return this->data_->array_[p.row()][p.col()]; - // return this->data_->array_[p.get_subject().row()][p.get_subject().col()]; - // return this->data_->array_ [*(coord_t*)(&p.get_subject())] [*((coord_t*)(&p.get_subject()) + 1)]; - return this->data_->array_ [*(coord_t*)(&p.p_hook_())] [*((coord_t*)(&p.p_hook_()) + 1)]; - // return this->data_->array_[0][0];; - } - - // Specific methods: // ----------------- @@ -255,11 +230,6 @@ namespace mln /// Give a hook to the value buffer. T* buffer(); - - /// \cond INTERNAL_API - /// Resize image border with new_border. - void resize_(unsigned new_border); - /// \endcond }; @@ -268,11 +238,8 @@ namespace mln /// \cond INTERNAL_API - template <typename T> - void init_(tag::border_t, unsigned& bdr, const image2d<T>& model); - template <typename T, typename J> - void init_(tag::image_t, mln::image2d<T>& target, const J& model); + void init_(tag::image_t, mln::image2d_ffmpeg<T>& target, const J& model); /// \endcond @@ -281,88 +248,53 @@ namespace mln // init_ - template <typename T> - inline - void init_(tag::border_t, unsigned& bdr, const image2d<T>& model) - { - bdr = model.border(); - } - template <typename T, typename J> inline - void init_(tag::image_t, image2d<T>& target, const J& model) + void init_(tag::image_t, image2d_ffmpeg<T>& target, const J& model) { box2d b; init_(tag::bbox, b, model); - unsigned bdr; - init_(tag::border, bdr, model); - target.init_(b, bdr); + target.init_(b); } - // internal::data< image2d<T> > + // internal::data< image2d_ffmpeg<T> > namespace internal { template <typename T> inline - data< image2d<T> >::data(const box2d& b, unsigned bdr) - : buffer_(0), - array_ (0), - b_ (b), - bdr_ (bdr) + data< image2d_ffmpeg<T> >::data(AVFrame *frame) + : frame_(frame) { - allocate_(); - } + b_ = make::box2d(frame->height, frame->width); - template <typename T> - inline - data< image2d<T> >::~data() - { - deallocate_(); - } - - template <typename T> - inline - void - data< image2d<T> >::update_vb_() - { - vb_.pmin() = b_.pmin() - dpoint2d(all_to(bdr_)); - vb_.pmax() = b_.pmax() + dpoint2d(all_to(bdr_)); - } - - template <typename T> - inline - void - data< image2d<T> >::allocate_() - { - update_vb_(); unsigned - nr = vb_.len(0), - nc = vb_.len(1); - buffer_ = new T[nr * nc]; + nr = frame->height, + nc = frame->width; array_ = new T*[nr]; - T* buf = buffer_ - vb_.pmin().col(); + buf_ = frame->data[0]; + T* buf = frame->data[0]; for (unsigned i = 0; i < nr; ++i) { array_[i] = buf; - buf += nc; + buf += frame->linesize; } - array_ -= vb_.pmin().row(); - mln_postcondition(vb_.len(0) == b_.len(0) + 2 * bdr_); - mln_postcondition(vb_.len(1) == b_.len(1) + 2 * bdr_); + } + + template <typename T> + inline + data< image2d_ffmpeg<T> >::~data() + { + deallocate_(); + // AVFrame must be deleted by the user! } template <typename T> inline void - data< image2d<T> >::deallocate_() + data< image2d_ffmpeg<T> >::deallocate_() { - if (buffer_) - { - delete[] buffer_; - buffer_ = 0; - } if (array_) { array_ += vb_.pmin().row(); @@ -371,64 +303,28 @@ namespace mln } } - template <typename T> - inline - void - data< image2d<T> >::swap_(data< image2d<T> >& other_) - { - data< image2d<T> > self_ = *this; - *this = other_; - other_ = self_; - } - - template <typename T> - inline - void - data< image2d<T> >::reallocate_(unsigned new_border) - { - data< image2d<T> >& tmp = *(new data< image2d<T> >(this->b_, new_border)); - this->swap_(tmp); - } - - } // end of namespace mln::internal - // image2d<T> - - template <typename T> - inline - image2d<T>::image2d() - { - } - - template <typename T> - inline - image2d<T>::image2d(int nrows, int ncols, unsigned bdr) - { - init_(make::box2d(nrows, ncols), bdr); - } + // image2d_ffmpeg<T> template <typename T> inline - image2d<T>::image2d(const box2d& b, unsigned bdr) + image2d_ffmpeg<T>::image2d_ffmpeg() { - init_(b, bdr); } template <typename T> inline - void - image2d<T>::init_(const box2d& b, unsigned bdr) + image2d_ffmpeg<T>::image2d_ffmpeg(AVFrame *frame) { - mln_precondition(! this->is_valid()); - this->data_ = new internal::data< image2d<T> >(b, bdr); + this->data_ = new internal::data< image2d_ffmpeg<T> >(frame); } template <typename T> inline const box2d& - image2d<T>::domain() const + image2d_ffmpeg<T>::domain() const { mln_precondition(this->is_valid()); return this->data_->b_; @@ -437,7 +333,7 @@ namespace mln template <typename T> inline const box2d& - image2d<T>::bbox() const + image2d_ffmpeg<T>::bbox() const { mln_precondition(this->is_valid()); return this->data_->b_; @@ -446,25 +342,25 @@ namespace mln template <typename T> inline const box2d& - image2d<T>::vbbox() const + image2d_ffmpeg<T>::vbbox() const { mln_precondition(this->is_valid()); - return this->data_->vb_; + return this->data_->b_; } template <typename T> inline bool - image2d<T>::has(const point2d& p) const + image2d_ffmpeg<T>::has(const point2d& p) const { mln_precondition(this->is_valid()); - return this->data_->vb_.has(p); + return this->data_->b_.has(p); } template <typename T> inline const T& - image2d<T>::operator()(const point2d& p) const + image2d_ffmpeg<T>::operator()(const point2d& p) const { mln_precondition(this->has(p)); return this->data_->array_[p.row()][p.col()]; @@ -473,7 +369,7 @@ namespace mln template <typename T> inline T& - image2d<T>::operator()(const point2d& p) + image2d_ffmpeg<T>::operator()(const point2d& p) { mln_precondition(this->has(p)); return this->data_->array_[p.row()][p.col()]; @@ -485,7 +381,7 @@ namespace mln template <typename T> inline const T& - image2d<T>::at_(mln::def::coord row, mln::def::coord col) const + image2d_ffmpeg<T>::at_(mln::def::coord row, mln::def::coord col) const { mln_precondition(this->has(point2d(row, col))); return this->data_->array_[row][col]; @@ -494,7 +390,7 @@ namespace mln template <typename T> inline T& - image2d<T>::at_(mln::def::coord row, mln::def::coord col) + image2d_ffmpeg<T>::at_(mln::def::coord row, mln::def::coord col) { mln_precondition(this->has(point2d(row, col))); return this->data_->array_[row][col]; @@ -503,7 +399,7 @@ namespace mln template <typename T> inline unsigned - image2d<T>::nrows() const + image2d_ffmpeg<T>::nrows() const { mln_precondition(this->is_valid()); return this->data_->b_.len(0); @@ -512,7 +408,7 @@ namespace mln template <typename T> inline unsigned - image2d<T>::ncols() const + image2d_ffmpeg<T>::ncols() const { mln_precondition(this->is_valid()); return this->data_->b_.len(1); @@ -524,25 +420,25 @@ namespace mln template <typename T> inline unsigned - image2d<T>::border() const + image2d_ffmpeg<T>::border() const { mln_precondition(this->is_valid()); - return this->data_->bdr_; + return 0; } template <typename T> inline unsigned - image2d<T>::nelements() const + image2d_ffmpeg<T>::nelements() const { mln_precondition(this->is_valid()); - return this->data_->vb_.nsites(); + return this->data_->b_.nsites(); } template <typename T> inline const T& - image2d<T>::element(unsigned i) const + image2d_ffmpeg<T>::element(unsigned i) const { mln_precondition(i < nelements()); return *(this->data_->buffer_ + i); @@ -551,7 +447,7 @@ namespace mln template <typename T> inline T& - image2d<T>::element(unsigned i) + image2d_ffmpeg<T>::element(unsigned i) { mln_precondition(i < nelements()); return *(this->data_->buffer_ + i); @@ -560,7 +456,7 @@ namespace mln template <typename T> inline const T* - image2d<T>::buffer() const + image2d_ffmpeg<T>::buffer() const { mln_precondition(this->is_valid()); return this->data_->buffer_; @@ -569,46 +465,36 @@ namespace mln template <typename T> inline T* - image2d<T>::buffer() + image2d_ffmpeg<T>::buffer() { mln_precondition(this->is_valid()); return this->data_->buffer_; } - template <typename T> - inline - int - image2d<T>::delta_offset(const dpoint2d& dp) const - { - mln_precondition(this->is_valid()); - int o = dp[0] * this->data_->vb_.len(1) + dp[1]; - return o; - } + // template <typename T> + // inline + // int + // image2d_ffmpeg<T>::delta_offset(const dpoint2d& dp) const + // { + // mln_precondition(this->is_valid()); + // int o = dp[0] * this->data_->frame->linesize + dp[1]; + // return o; + // } + + // template <typename T> + // inline + // point2d + // image2d_ffmpeg<T>::point_at_offset(unsigned i) const + // { + // mln_precondition(i < nelements()); + // def::coord + // row = static_cast<def::coord>(i / this->data_->vb_.len(1) + this->data_->vb_.min_row()), + // col = static_cast<def::coord>(i % this->data_->vb_.len(1) + this->data_->vb_.min_col()); + // point2d p = point2d(row, col); + // mln_postcondition(& this->operator()(p) == this->data_->buffer_ + i); + // return p; + // } - template <typename T> - inline - point2d - image2d<T>::point_at_offset(unsigned i) const - { - mln_precondition(i < nelements()); - def::coord - row = static_cast<def::coord>(i / this->data_->vb_.len(1) + this->data_->vb_.min_row()), - col = static_cast<def::coord>(i % this->data_->vb_.len(1) + this->data_->vb_.min_col()); - point2d p = point2d(row, col); - mln_postcondition(& this->operator()(p) == this->data_->buffer_ + i); - return p; - } - - // Extra. - - template <typename T> - inline - void - image2d<T>::resize_(unsigned new_border) - { - mln_precondition(this->is_valid()); - this->data_->reallocate_(new_border); - } # endif // ! MLN_INCLUDE_ONLY @@ -631,79 +517,79 @@ namespace mln // pixter template <typename T> - struct fwd_pixter< image2d<T> > + struct fwd_pixter< image2d_ffmpeg<T> > { - typedef fwd_pixter2d< image2d<T> > ret; + typedef fwd_pixter2d< image2d_ffmpeg<T> > ret; }; template <typename T> - struct fwd_pixter< const image2d<T> > + struct fwd_pixter< const image2d_ffmpeg<T> > { - typedef fwd_pixter2d< const image2d<T> > ret; + typedef fwd_pixter2d< const image2d_ffmpeg<T> > ret; }; template <typename T> - struct bkd_pixter< image2d<T> > + struct bkd_pixter< image2d_ffmpeg<T> > { - typedef bkd_pixter2d< image2d<T> > ret; + typedef bkd_pixter2d< image2d_ffmpeg<T> > ret; }; template <typename T> - struct bkd_pixter< const image2d<T> > + struct bkd_pixter< const image2d_ffmpeg<T> > { - typedef bkd_pixter2d< const image2d<T> > ret; + typedef bkd_pixter2d< const image2d_ffmpeg<T> > ret; }; // qixter template <typename T, typename W> - struct fwd_qixter< image2d<T>, W > + struct fwd_qixter< image2d_ffmpeg<T>, W > { - typedef dpoints_fwd_pixter< image2d<T> > ret; + typedef dpoints_fwd_pixter< image2d_ffmpeg<T> > ret; }; template <typename T, typename W> - struct fwd_qixter< const image2d<T>, W > + struct fwd_qixter< const image2d_ffmpeg<T>, W > { - typedef dpoints_fwd_pixter< const image2d<T> > ret; + typedef dpoints_fwd_pixter< const image2d_ffmpeg<T> > ret; }; template <typename T, typename W> - struct bkd_qixter< image2d<T>, W > + struct bkd_qixter< image2d_ffmpeg<T>, W > { - typedef dpoints_bkd_pixter< image2d<T> > ret; + typedef dpoints_bkd_pixter< image2d_ffmpeg<T> > ret; }; template <typename T, typename W> - struct bkd_qixter< const image2d<T>, W > + struct bkd_qixter< const image2d_ffmpeg<T>, W > { - typedef dpoints_bkd_pixter< const image2d<T> > ret; + typedef dpoints_bkd_pixter< const image2d_ffmpeg<T> > ret; }; // nixter template <typename T, typename N> - struct fwd_nixter< image2d<T>, N > + struct fwd_nixter< image2d_ffmpeg<T>, N > { - typedef dpoints_fwd_pixter< image2d<T> > ret; + typedef dpoints_fwd_pixter< image2d_ffmpeg<T> > ret; }; template <typename T, typename N> - struct fwd_nixter< const image2d<T>, N > + struct fwd_nixter< const image2d_ffmpeg<T>, N > { - typedef dpoints_fwd_pixter< const image2d<T> > ret; + typedef dpoints_fwd_pixter< const image2d_ffmpeg<T> > ret; }; template <typename T, typename N> - struct bkd_nixter< image2d<T>, N > + struct bkd_nixter< image2d_ffmpeg<T>, N > { - typedef dpoints_bkd_pixter< image2d<T> > ret; + typedef dpoints_bkd_pixter< image2d_ffmpeg<T> > ret; }; template <typename T, typename N> - struct bkd_nixter< const image2d<T>, N > + struct bkd_nixter< const image2d_ffmpeg<T>, N > { - typedef dpoints_bkd_pixter< const image2d<T> > ret; + typedef dpoints_bkd_pixter< const image2d_ffmpeg<T> > ret; }; } // end of namespace mln::trait @@ -711,8 +597,4 @@ namespace mln } // end of namespace mln -# include <mln/make/image.hh> -# include <mln/make/image2d.hh> - - -#endif // ! MLN_CORE_IMAGE_IMAGE2D_HH +#endif // ! MLN_CORE_IMAGE_IMAGE2D_FFMPEG_HH -- 1.7.2.5