• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

GnashImage.h

Go to the documentation of this file.
00001 // GnashImage.h: Base class for reading image data in Gnash.
00002 // 
00003 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
00004 //   Foundation, Inc
00005 // 
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation; either version 3 of the License, or
00009 // (at your option) any later version.
00010 // 
00011 // This program is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 // 
00016 // You should have received a copy of the GNU General Public License
00017 // along with this program; if not, write to the Free Software
00018 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019 //
00020 
00021 // The GnashImage class and subclasses are partly based on the public domain
00022 // work of Thatcher Ulrich <tu@tulrich.com> 2002
00023 
00024 #ifndef GNASH_GNASHIMAGE_H
00025 #define GNASH_GNASHIMAGE_H
00026 
00027 #include <boost/shared_ptr.hpp>
00028 #include <boost/noncopyable.hpp>
00029 #include <boost/cstdint.hpp>
00030 #include <boost/scoped_array.hpp>
00031 #include <memory> 
00032 #include <boost/iterator/iterator_facade.hpp>
00033 #include <iterator>
00034 
00035 #include "FileTypes.h"
00036 #include "log.h"
00037 #include "dsodefs.h"
00038 
00039 // Forward declarations
00040 namespace gnash {
00041     class IOChannel;
00042     class JpegImageInput;
00043 }
00044 
00045 namespace gnash {
00046 
00048 enum ImageType
00049 {
00050     GNASH_IMAGE_INVALID,
00051     GNASH_IMAGE_RGB,
00052     GNASH_IMAGE_RGBA
00053 };
00054 
00056 enum ImageLocation
00057 {
00058     GNASH_IMAGE_CPU = 1,
00059     GNASH_IMAGE_GPU
00060 };
00061 
00062 inline size_t
00063 numChannels(ImageType t)
00064 {
00065     switch (t) {
00066         case GNASH_IMAGE_RGBA:
00067             return 4;
00068         case GNASH_IMAGE_RGB:
00069             return 3;
00070         default:
00071             std::abort();
00072     }
00073 }
00074 
00075 template<typename Iterator>
00076 class ARGB
00077 {
00078 public:
00079 
00080     ARGB(Iterator i, ImageType t)
00081         :
00082         _it(i),
00083         _t(t)
00084     {}
00085     
00087     //
00089     ARGB& operator=(boost::uint32_t pixel) {
00090         switch (_t) {
00091             case GNASH_IMAGE_RGBA:
00092                 // alpha
00093                 *(_it + 3) = (pixel & 0xff000000) >> 24;
00094             case GNASH_IMAGE_RGB:
00095                 *_it = (pixel & 0x00ff0000) >> 16;
00096                 *(_it + 1) = (pixel & 0x0000ff00) >> 8;
00097                 *(_it + 2) = (pixel & 0x000000ff);
00098             default:
00099                 break;
00100         }
00101         return *this;
00102     }
00103 
00104 private:
00105     Iterator _it;
00106     ImageType _t;
00107 };
00108 
00109 template<typename Iterator, typename Pixel>
00110 struct pixel_iterator : public boost::iterator_facade<
00111                             pixel_iterator<Iterator, Pixel>,
00112                             boost::uint32_t,
00113                             std::random_access_iterator_tag,
00114                             Pixel>
00115 {
00116 
00117     typedef std::ptrdiff_t difference_type;
00118 
00119     pixel_iterator(Iterator it, ImageType t)
00120         :
00121         _it(it),
00122         _t(t)
00123     {}
00124  
00125     boost::uint32_t toARGB() const {
00126         boost::uint32_t ret = 0xff000000;
00127         switch (_t) {
00128             case GNASH_IMAGE_RGBA:
00129                 // alpha
00130                 ret = *(_it + 3) << 24;
00131             case GNASH_IMAGE_RGB:
00132                 ret |= (*_it << 16 | *(_it + 1) << 8 | *(_it + 2));
00133             default:
00134                 break;
00135         }
00136         return ret;
00137     }
00138 
00139 private:
00140 
00141     friend class boost::iterator_core_access;
00142 
00143     Pixel dereference() const {
00144         return Pixel(_it, _t);
00145     }
00146 
00147     void increment() {
00148         _it += numChannels(_t);
00149     }
00150 
00151     bool equal(const pixel_iterator& o) const {
00152         return o._it == _it;
00153     }
00154 
00155     difference_type distance_to(const pixel_iterator& o) const {
00156         return (o._it - _it) / numChannels(_t);
00157     }
00158 
00159     void advance(difference_type n) {
00160         _it += n * numChannels(_t);
00161     }
00162 
00163     Iterator _it;
00164     ImageType _t;
00165 };
00166 
00168 //
00171 class DSOEXPORT GnashImage : boost::noncopyable
00172 {
00173 public:
00174 
00175     typedef boost::uint8_t value_type;
00176     typedef boost::scoped_array<value_type> container_type;
00177     typedef value_type* iterator;
00178     typedef const value_type* const_iterator;
00179 
00180     typedef pixel_iterator<iterator, ARGB<iterator> > argb_iterator;
00181 
00182     virtual ~GnashImage() {}
00183 
00185     //
00187     ImageType type() const {
00188         return _type;
00189     }
00190 
00192     //
00194     ImageLocation location() const {
00195         return _location;
00196     }
00197 
00199     //
00201     size_t size() const {
00202         return stride() * _height;
00203     }
00204 
00206     //
00208     virtual size_t stride() const {
00209         return _width * channels();
00210     }
00211 
00213     //
00215     size_t channels() const {
00216         return numChannels(_type);
00217     }
00218 
00220     //
00222     size_t width() const {
00223         return _width;
00224     }
00225 
00227     //
00229     size_t height() const {
00230         return _height;
00231     }
00232 
00234     //
00240     void update(const_iterator data);
00241 
00243     //
00247     void update(const GnashImage& from);
00248     
00250     virtual iterator begin() {
00251         return _data.get();
00252     }
00253 
00255     virtual const_iterator begin() const {
00256         return _data.get();
00257     }
00258 
00260     iterator end() {
00261         return begin() + size();
00262     }
00263 
00265     const_iterator end() const {
00266         return begin() + size();
00267     }
00268 
00270     argb_iterator argb_begin() {
00271         return argb_iterator(begin(), _type);
00272     }
00273     
00275     argb_iterator argb_end() {
00276         return argb_iterator(end(), _type);
00277     }
00278 
00279 protected:
00280 
00282     //
00288     GnashImage(iterator data, size_t width, size_t height, ImageType type,
00289             ImageLocation location = GNASH_IMAGE_CPU);
00290 
00292     //
00295     //
00299     GnashImage(size_t width, size_t height, ImageType type,
00300                ImageLocation location = GNASH_IMAGE_CPU);
00301 
00302 
00304     const ImageType _type;
00305 
00307     const ImageLocation _location;
00308 
00310     const size_t _width;
00311 
00313     const size_t _height;
00314 
00316     container_type _data;
00317 
00318 };
00319 
00321 //
00323 class DSOEXPORT ImageRGB : public GnashImage
00324 {
00325 public:
00326 
00328     ImageRGB(size_t width, size_t height);
00329 
00331     ImageRGB(iterator data, size_t width, size_t height)
00332         :
00333         GnashImage(data, width, height, GNASH_IMAGE_RGB)
00334     {}
00335 
00336     virtual ~ImageRGB();
00337 };
00338 
00340 //
00342 class DSOEXPORT ImageRGBA : public GnashImage
00343 {
00344 
00345 public:
00346 
00348     ImageRGBA(size_t width, size_t height);
00349 
00350     ImageRGBA(iterator data, size_t width, size_t height)
00351         :
00352         GnashImage(data, width, height, GNASH_IMAGE_RGBA)
00353     {}
00354     
00355     ~ImageRGBA();
00356 
00358     //
00361     void setPixel(size_t x, size_t y, value_type r, value_type g, value_type b,
00362             value_type a);
00363 
00364     void mergeAlpha(const_iterator alphaData, const size_t bufferLength);
00365 
00366 };
00367 
00369 class ImageInput : boost::noncopyable
00370 {
00371 public:
00372 
00374     //
00378     ImageInput(boost::shared_ptr<IOChannel> in)
00379         :
00380         _inStream(in),
00381         _type(GNASH_IMAGE_INVALID)
00382     {}
00383 
00384     virtual ~ImageInput() {}
00385 
00387     virtual void read() = 0;
00388 
00390     //
00392     virtual size_t getHeight() const = 0;
00393 
00395     //
00397     virtual size_t getWidth() const = 0;
00398 
00400     //
00402     virtual size_t getComponents() const = 0;
00403 
00405     //
00407     virtual void readScanline(unsigned char* rgbData) = 0;
00408 
00410     //
00414     ImageType imageType() { return _type; }
00415 
00419     DSOEXPORT static std::auto_ptr<ImageRGBA> readSWFJpeg3(
00420             boost::shared_ptr<gnash::IOChannel> in);
00421 
00423     //
00429     DSOEXPORT static std::auto_ptr<GnashImage> readImageData(
00430             boost::shared_ptr<gnash::IOChannel> in, FileType type);
00431 
00432 protected:
00433 
00434     boost::shared_ptr<IOChannel> _inStream;
00435 
00436     ImageType _type;
00437 
00438 };
00439 
00440 // Base class for writing image data.
00441 class ImageOutput : boost::noncopyable
00442 {
00443 
00444 public:
00445 
00447     //
00452     ImageOutput(boost::shared_ptr<IOChannel> out, size_t width, size_t height)
00453         :
00454         _width(width),
00455         _height(height),
00456         _outStream(out)
00457     {}
00458 
00459     virtual ~ImageOutput() {}
00460     
00462     //
00464     virtual void writeImageRGB(const unsigned char* rgbData) = 0;
00465     
00467     //
00469     virtual void writeImageRGBA(const unsigned char* /*rgbaData*/)
00470     {
00471         log_error(_("This image format does not support writing RGBA images"));
00472     }
00473 
00475     //
00481     DSOEXPORT static void writeImageData(FileType type,
00482             boost::shared_ptr<gnash::IOChannel> out, const GnashImage& image,
00483             int quality);
00484 
00485 protected:
00486 
00487     const size_t _width;
00488 
00489     const size_t _height;
00490     
00491     boost::shared_ptr<IOChannel> _outStream;
00492 
00493 };
00494 
00496 //
00499 inline GnashImage::iterator
00500 scanline(GnashImage& im, size_t row)
00501 {
00502     assert(row < im.height());
00503     return im.begin() + im.stride() * row;
00504 }
00505 
00507 //
00510 inline GnashImage::const_iterator
00511 scanline(const GnashImage& im, size_t row)
00512 {
00513     assert(row < im.height());
00514     return im.begin() + im.stride() * row;
00515 }
00516 
00517 } // namespace gnash
00518 
00519 #endif

Generated on Fri Mar 16 2012 15:46:10 for Gnash by  doxygen 1.7.1