gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/trunk r9589: Various image-related bugfixe


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r9589: Various image-related bugfixes and improvements.
Date: Wed, 13 Aug 2008 12:51:20 +0200
User-agent: Bazaar (1.5)

------------------------------------------------------------
revno: 9589
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Wed 2008-08-13 12:51:20 +0200
message:
  Various image-related bugfixes and improvements.
added:
  testsuite/media/greyscale.png
  testsuite/media/indexed.png
modified:
  libbase/GnashImagePng.cpp
  libbase/GnashImagePng.h
  libbase/image.cpp
  libbase/image.h
  libcore/asobj/NetStream.cpp
  libcore/asobj/NetStream.h
  testsuite/misc-ming.all/loadImageTest.c
    ------------------------------------------------------------
    revno: 9588.1.1
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Wed 2008-08-13 09:32:20 +0200
    message:
      Return m_imageframe (auto_ptr<image_base>) directly instead of cloning
      (will save a heap allocation and memcpy for every frame of a streaming 
video.
      
      Use legal header guard.
    modified:
      libcore/asobj/NetStream.cpp
      libcore/asobj/NetStream.h
    ------------------------------------------------------------
    revno: 9588.1.2
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Wed 2008-08-13 09:33:35 +0200
    message:
      Drop pure virtual clone method of image_base as it's currently unused.
      Was there a point in making it pure?
      
      Drop unused alpha::operator== and const image_base::scanline(), which was
      only used in that operator.
      
      Move ImageType enum to the image namespace as it will be used more widely.
      Provide accessor.
    modified:
      libbase/image.cpp
      libbase/image.h
    ------------------------------------------------------------
    revno: 9588.1.3
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Wed 2008-08-13 11:46:50 +0200
    message:
      Convert single channel data to RGB instead of messing it up. Strip 16-bit
      channels to 8-bit channels to suit image::rgb.
    modified:
      libbase/GnashImagePng.cpp
      libbase/GnashImagePng.h
    ------------------------------------------------------------
    revno: 9588.1.4
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Wed 2008-08-13 11:48:52 +0200
    message:
      Use image::image_base::type instead of dynamic_cast to decide how to write
      images. Rename image type enum.
    modified:
      libbase/image.cpp
      libbase/image.h
    ------------------------------------------------------------
    revno: 9588.1.5
    committer: Benjamin Wolsey <address@hidden>
    branch nick: work
    timestamp: Wed 2008-08-13 12:05:12 +0200
    message:
      Add greyscale and indexed png (the latter doesn't display properly).
    added:
      testsuite/media/greyscale.png
      testsuite/media/indexed.png
    modified:
      testsuite/misc-ming.all/loadImageTest.c
=== modified file 'libbase/GnashImagePng.cpp'
--- a/libbase/GnashImagePng.cpp 2008-08-12 20:29:22 +0000
+++ b/libbase/GnashImagePng.cpp 2008-08-13 09:46:50 +0000
@@ -71,6 +71,7 @@
     ImageInput(in),
     _pngPtr(0),
     _infoPtr(0),
+    _rowPtrs(0),
     _currentRow(0)
 {
     init();
@@ -99,11 +100,47 @@
 PngImageInput::readScanline(unsigned char* rgbData)
 {
     assert (_currentRow < getHeight());
-    png_bytepp row_pointers = png_get_rows(_pngPtr, _infoPtr);
-    std::memcpy(rgbData, row_pointers[_currentRow], getWidth() * 
getComponents());
+    assert (_rowPtrs);
+   
+    const size_t components = getComponents();
+
+    // Bit-depth must be 8!
+    assert (png_get_rowbytes(_pngPtr, _infoPtr) == components * getWidth());
+    
+    switch (components)
+    {
+
+        case 3:
+            // Data packed as RGB
+            std::memcpy(rgbData, _rowPtrs[_currentRow],
+                        getWidth() * components);
+            break;
+
+        case 1:
+            // Greyscale data: we have to convert to RGB
+            for (size_t x = 0; x < getWidth(); ++x)
+            {
+                std::memset(rgbData, _rowPtrs[_currentRow][x], 3);
+                rgbData += 3;
+            }
+            break;
+
+        default:
+            boost::format fmt = boost::format("Cannot handle pixels "
+                                     "with %d channels!") % components;
+            throw ParserException(fmt.str());
+
+    }
+    
     ++_currentRow;
 }
 
+size_t
+PngImageInput::getComponents() const
+{
+    return png_get_channels(_pngPtr, _infoPtr);
+}
+
 void
 PngImageInput::init()
 {
@@ -127,9 +164,15 @@
     // Set our user-defined reader function
     png_set_read_fn(_pngPtr, _inStream.get(), &readData);
     
-    // read
+    // read PNG into memory.
     // TODO: sort out transform options.
-    png_read_png(_pngPtr, _infoPtr, PNG_TRANSFORM_STRIP_ALPHA, NULL);
+    // At present we strip alpha because Gnash can't handle it and reduce the 
bit depth
+    // to 8 bits, as that's all the image class can handle.
+    png_read_png(_pngPtr, _infoPtr, PNG_TRANSFORM_STRIP_ALPHA | 
PNG_TRANSFORM_STRIP_16, NULL);
+
+    // Allocate and fill array of pointers to each row. This should be
+    // cleaned up by png_destroy_read_struct.
+    _rowPtrs = png_get_rows(_pngPtr, _infoPtr);    
 }
 
 ///

=== modified file 'libbase/GnashImagePng.h'
--- a/libbase/GnashImagePng.h   2008-08-12 10:58:20 +0000
+++ b/libbase/GnashImagePng.h   2008-08-13 09:46:50 +0000
@@ -42,6 +42,7 @@
        // State needed for input.
     png_structp _pngPtr;
     png_infop _infoPtr;
+    png_bytepp _rowPtrs;
    
     // A counter for keeping track of the last row copied.
     size_t _currentRow;
@@ -71,7 +72,7 @@
        // data).  The size of the data for a scanline is
        // get_width() * get_components().
        //
-       int     getComponents() const { return 3; }
+       size_t getComponents() const;
 
        // Read a scanline's worth of image data into the
        // given buffer.  The amount of data read is

=== modified file 'libbase/image.cpp'
--- a/libbase/image.cpp 2008-08-12 10:58:20 +0000
+++ b/libbase/image.cpp 2008-08-13 09:48:52 +0000
@@ -28,9 +28,9 @@
        //
 
        /// Create an image taking ownership of the given buffer, supposedly of 
height*pitch bytes
-       image_base::image_base(boost::uint8_t* data, int width, int height, int 
pitch, id_image type)
+       image_base::image_base(boost::uint8_t* data, int width, int height, int 
pitch, ImageType type)
                :
-               m_type(type),
+               _type(type),
                m_size(height*pitch),
                m_width(width),
                m_height(height),
@@ -40,9 +40,9 @@
        }
 
        /// Create an image allocating a buffer of height*pitch bytes
-       image_base::image_base(int width, int height, int pitch, id_image type)
+       image_base::image_base(int width, int height, int pitch, ImageType type)
                :
-               m_type(type),
+               _type(type),
                m_size(height*pitch),
                m_width(width),
                m_height(height),
@@ -61,7 +61,7 @@
        {
                assert(from.m_pitch == m_pitch);
                assert(m_size <= from.m_size);
-               assert(m_type == from.m_type);
+               assert(_type == from._type);
                std::memcpy(m_data.get(), const_cast<image_base&>(from).data(), 
m_size);
        }
 
@@ -85,7 +85,7 @@
                :
                image_base( width, height,
                        (width * 3 + 3) & ~3, // round pitch up to nearest 
4-byte boundary
-                       RGB)
+                       GNASH_IMAGE_RGB)
        {
                assert(width > 0);
                assert(height > 0);
@@ -105,7 +105,7 @@
 
        rgba::rgba(int width, int height)
                :
-               image_base(width, height, width * 4, RGBA)
+               image_base(width, height, width * 4, GNASH_IMAGE_RGBA)
        {
                assert(width > 0);
                assert(height > 0);
@@ -149,7 +149,7 @@
 
        alpha::alpha(int width, int height)
                :
-               image_base(width, height, width, ALPHA)
+               image_base(width, height, width, GNASH_IMAGE_ALPHA)
        {
                assert(width > 0);
                assert(height > 0);
@@ -160,29 +160,6 @@
        {
        }
 
-
-       bool    alpha::operator==(const alpha& a) const
-       // Bitwise content comparison.
-       {
-               if (m_width != a.m_width
-                   || m_height != a.m_height)
-               {
-                       return false;
-               }
-
-               for (int j = 0, n = m_height; j < n; j++)
-               {
-                       if (memcmp(scanline(j), a.scanline(j), m_width))
-                       {
-                               // Mismatch.
-                               return false;
-                       }
-               }
-
-               // Images are identical.
-               return true;
-       }
-
        //
        // utility
        //
@@ -209,18 +186,18 @@
                 break;
         }
 
-        image::rgb* imageRGB = dynamic_cast<image::rgb*>(image);
-        if (imageRGB)
+        switch (image->type())
         {
-            outChannel->writeImageRGB(imageRGB->data());
-            return;        
+            case GNASH_IMAGE_RGB:
+                outChannel->writeImageRGB(image->data());
+                break;
+            case GNASH_IMAGE_RGBA:
+                outChannel->writeImageRGBA(image->data());
+                break;
+            default:
+                break;
         }
 
-        image::rgba* imageRGBA = dynamic_cast<image::rgba*>(image);
-        if (imageRGBA)
-        {
-            outChannel->writeImageRGBA(imageRGBA->data());
-        }
        }
 
     // See gnash.h for file types.

=== modified file 'libbase/image.h'
--- a/libbase/image.h   2008-08-11 16:42:50 +0000
+++ b/libbase/image.h   2008-08-13 09:48:52 +0000
@@ -27,24 +27,23 @@
 {
 namespace image
 {
+
+enum ImageType
+{
+       GNASH_IMAGE_INVALID,
+       GNASH_IMAGE_RGB,
+       GNASH_IMAGE_RGBA,
+       GNASH_IMAGE_ALPHA
+};
+
        /// Base class for different types of images
        class DSOEXPORT image_base
        {
        public:
-               enum id_image
-               {
-                       INVALID,
-                       RGB,
-                       RGBA,
-                       ALPHA,
-                       ROW
-               };
-
-               id_image m_type;
 
                image_base(const image_base& o)
                        :
-                       m_type(o.m_type),
+                       _type(o._type),
                        m_size(o.size()),
                        m_width(o.width()),
                        m_height(o.height()),
@@ -54,13 +53,12 @@
                        update(o);
                }
                        
-               image_base(boost::uint8_t *data, int width, int height, int 
pitch, id_image type);
+               image_base(boost::uint8_t *data, int width, int height, int 
pitch, ImageType type);
 
                /// Construct an image_base allocating data for height*pitch 
bytes
-               image_base(int width, int height, int pitch, id_image type);
+               image_base(int width, int height, int pitch, ImageType type);
 
-               /// Return a copy of this image
-               virtual std::auto_ptr<image_base> clone() const=0;
+        ImageType type() const { return _type; }
 
                /// Return size of this image buffer, in bytes
                size_t size() const { return m_size; }
@@ -92,7 +90,7 @@
 
                /// Copy image data from another image data
                //
-               /// Note that this buffer MUST have the same m_pitch and m_type
+               /// Note that this buffer MUST have the same m_pitch and _type
                /// or an assertion will fail.
                ///
                /// @param from image to copy data from.
@@ -107,17 +105,13 @@
                /// Return a pointer to first byte of given line
                DSOEXPORT boost::uint8_t* scanline(size_t y);
 
-               /// Return a read-only pointer to first byte of given line
-               DSOEXPORT const boost::uint8_t* scanline(size_t y) const
-               {
-                       return const_cast<image_base*>(this)->scanline(y);
-               }
-
                virtual ~image_base() {}
 
 
        protected:
 
+               const ImageType _type;
+
                /// Size of image buffer in bytes.
                const size_t m_size;
 
@@ -156,14 +150,9 @@
                {}
 
                rgb(boost::uint8_t* data, int width, int height, int stride)
-                       : image_base(data, width, height, stride, RGB)
+                       : image_base(data, width, height, stride, 
GNASH_IMAGE_RGB)
                {}
 
-               std::auto_ptr<image_base> clone() const
-               {
-                       return std::auto_ptr<image_base>(new rgb(*this));
-               }
-
                ~rgb();
 
        };
@@ -183,12 +172,6 @@
 
                ~rgba();
 
-               std::auto_ptr<image_base> clone() const
-               {
-                       return std::auto_ptr<image_base>(new rgba(*this));
-               }
-
-
                /// Set pixel value 
                //
                /// TODO: move in base class ?
@@ -210,11 +193,6 @@
                        image_base(o)
                {}
 
-               std::auto_ptr<image_base> clone() const
-               {
-                       return std::auto_ptr<image_base>(new alpha(*this));
-               }
-
                ~alpha();
 
                /// Set pixel value 
@@ -223,9 +201,6 @@
                ///
                void    set_pixel(size_t x, size_t y, boost::uint8_t a);
 
-               // Bitwise content comparison.
-               bool    operator==(const alpha& a) const;
-
        };
 
        /// Write the given image to the given out channel in a specified 
format.

=== modified file 'libcore/asobj/NetStream.cpp'
--- a/libcore/asobj/NetStream.cpp       2008-07-10 14:54:56 +0000
+++ b/libcore/asobj/NetStream.cpp       2008-08-13 07:32:20 +0000
@@ -560,7 +560,7 @@
        if (!m_imageframe.get()) return std::auto_ptr<image::image_base>(0);
 
        // TODO: inspect if we could return m_imageframe directly...
-       return m_imageframe->clone();   
+       return m_imageframe;    
 }
 
 std::pair<const char*, const char*>

=== modified file 'libcore/asobj/NetStream.h'
--- a/libcore/asobj/NetStream.h 2008-07-10 14:54:56 +0000
+++ b/libcore/asobj/NetStream.h 2008-08-13 07:32:20 +0000
@@ -16,8 +16,8 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 
-#ifndef __NETSTREAM_H__
-#define __NETSTREAM_H__
+#ifndef GNASH_NETSTREAM_H
+#define GNASH_NETSTREAM_H
 
 #ifdef HAVE_CONFIG_H
 #include "gnashconfig.h"

=== added file 'testsuite/media/greyscale.png'
Binary files a/testsuite/media/greyscale.png    1970-01-01 00:00:00 +0000 and 
b/testsuite/media/greyscale.png   2008-08-13 10:05:12 +0000 differ
=== added file 'testsuite/media/indexed.png'
Binary files a/testsuite/media/indexed.png      1970-01-01 00:00:00 +0000 and 
b/testsuite/media/indexed.png     2008-08-13 10:05:12 +0000 differ
=== modified file 'testsuite/misc-ming.all/loadImageTest.c'
--- a/testsuite/misc-ming.all/loadImageTest.c   2008-08-06 09:18:04 +0000
+++ b/testsuite/misc-ming.all/loadImageTest.c   2008-08-13 10:05:12 +0000
@@ -125,14 +125,19 @@
        SWFMovieClip dejagnuclip;
        SWFDisplayItem it;
 
-       char url_png[256];
-    char url_gif[256];
-    char url_igif[256];
+       char url_png[512];
+    char url_indexpng[512];
+    char url_greypng[512];
+    char url_gif[512];
+    char url_igif[512];
 
     char png_action[256];
+    char indexpng_action[256];
+    char greypng_action[256];
     char gif_action[256];
     char igif_action[256];
 
+
        /*********************************************
         *
         * Initialization
@@ -147,6 +152,8 @@
        }
 
        sprintf(url_png, "%s/png.png", mediadir);
+       sprintf(url_indexpng, "%s/indexed.png", mediadir);
+       sprintf(url_greypng, "%s/greyscale.png", mediadir);
        sprintf(url_gif, "%s/gif.gif", mediadir);
        sprintf(url_igif, "%s/gif-interlaced.gif", mediadir);
 
@@ -181,8 +188,14 @@
     sprintf(png_action, "_root.window.loadMovie(\"%s\");", url_png);
     add_button(mo, 50, 100, "Load PNG", newSWFAction(png_action));
 
+    sprintf(indexpng_action, "_root.window.loadMovie(\"%s\");", url_indexpng);
+    add_button(mo, 50, 125, "Load indexed PNG", newSWFAction(indexpng_action));
+
+    sprintf(greypng_action, "_root.window.loadMovie(\"%s\");", url_greypng);
+    add_button(mo, 50, 150, "Load greyscale PNG", 
newSWFAction(greypng_action));
+
     sprintf(gif_action, "_root.window.loadMovie(\"%s\");", url_gif);
-    add_button(mo, 50, 150, "Load GIF", newSWFAction(gif_action));
+    add_button(mo, 50, 175, "Load GIF", newSWFAction(gif_action));
 
     sprintf(igif_action, "_root.window.loadMovie(\"%s\");", url_igif);
     add_button(mo, 50, 200, "Load interlaced GIF", newSWFAction(igif_action));


reply via email to

[Prev in Thread] Current Thread [Next in Thread]