Index: typedefs.hpp
===================================================================
--- typedefs.hpp	(revision 42242)
+++ typedefs.hpp	(working copy)
@@ -105,6 +105,13 @@
 GIL_DEFINE_BASE_TYPEDEFS(32 ,gray)
 GIL_DEFINE_BASE_TYPEDEFS(32s,gray)
 GIL_DEFINE_BASE_TYPEDEFS(32f,gray)
+GIL_DEFINE_BASE_TYPEDEFS(8,  alpha_gray)
+GIL_DEFINE_BASE_TYPEDEFS(8s, alpha_gray)
+GIL_DEFINE_BASE_TYPEDEFS(16, alpha_gray)
+GIL_DEFINE_BASE_TYPEDEFS(16s,alpha_gray)
+GIL_DEFINE_BASE_TYPEDEFS(32 ,alpha_gray)
+GIL_DEFINE_BASE_TYPEDEFS(32s,alpha_gray)
+GIL_DEFINE_BASE_TYPEDEFS(32f,alpha_gray)
 GIL_DEFINE_BASE_TYPEDEFS(8,  bgr)
 GIL_DEFINE_BASE_TYPEDEFS(8s, bgr)
 GIL_DEFINE_BASE_TYPEDEFS(16, bgr)
@@ -148,6 +155,13 @@
 GIL_DEFINE_ALL_TYPEDEFS(32 ,rgba)
 GIL_DEFINE_ALL_TYPEDEFS(32s,rgba)
 GIL_DEFINE_ALL_TYPEDEFS(32f,rgba)
+GIL_DEFINE_ALL_TYPEDEFS(8,  gray_alpha)
+GIL_DEFINE_ALL_TYPEDEFS(8s, gray_alpha)
+GIL_DEFINE_ALL_TYPEDEFS(16, gray_alpha)
+GIL_DEFINE_ALL_TYPEDEFS(16s,gray_alpha)
+GIL_DEFINE_ALL_TYPEDEFS(32 ,gray_alpha)
+GIL_DEFINE_ALL_TYPEDEFS(32s,gray_alpha)
+GIL_DEFINE_ALL_TYPEDEFS(32f,gray_alpha)
 GIL_DEFINE_ALL_TYPEDEFS(8,  cmyk)
 GIL_DEFINE_ALL_TYPEDEFS(8s, cmyk)
 GIL_DEFINE_ALL_TYPEDEFS(16, cmyk)
Index: gray_alpha.hpp
===================================================================
--- gray_alpha.hpp	(revision 0)
+++ gray_alpha.hpp	(revision 0)
@@ -0,0 +1,26 @@
+
+/*
+    Copyright 2007 Andreas Pokorny
+   
+    Use, modification and distribution are subject to the Boost Software License,
+    Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+    http://www.boost.org/LICENSE_1_0.txt).
+
+    See http://opensource.adobe.com/gil for most recent version including documentation.
+*/
+
+#ifndef GIL_GRAY_ALPHA_H
+#define GIL_GRAY_ALPHA_H
+#include "gil_config.hpp"
+#include <boost/mpl/contains.hpp>
+#include "gray.hpp"
+#include "rgba.hpp"
+namespace boost { namespace gil {
+
+typedef mpl::vector2<gray_color_t,alpha_t> gray_alpha_t;
+
+typedef layout<gray_alpha_t> gray_alpha_layout_t;
+typedef layout<gray_alpha_layout_t, mpl::vector2_c<int,1,0> > alpha_gray_layout_t;
+}}
+
+#endif

Property changes on: gray_alpha.hpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Index: utilities.hpp
===================================================================
--- utilities.hpp	(revision 42242)
+++ utilities.hpp	(working copy)
@@ -326,6 +326,7 @@
     return !little_endian();
 }
 
+
 } }  // namespace boost::gil
 
 #endif
Index: bit_aligned_pixel_iterator.hpp
===================================================================
--- bit_aligned_pixel_iterator.hpp	(revision 42242)
+++ bit_aligned_pixel_iterator.hpp	(working copy)
@@ -114,6 +114,10 @@
 template <typename NonAlignedPixelReference>
 struct is_planar<bit_aligned_pixel_iterator<NonAlignedPixelReference> > : public is_planar<NonAlignedPixelReference> {}; // == false
 
+template <typename NonAlignedPixelReference>
+struct channel_type<bit_aligned_pixel_iterator<NonAlignedPixelReference> > : public channel_type<NonAlignedPixelReference> {
+};
+
 /////////////////////////////
 //  MemoryBasedIteratorConcept
 /////////////////////////////
Index: color_convert.hpp
===================================================================
--- color_convert.hpp	(revision 42242)
+++ color_convert.hpp	(working copy)
@@ -29,6 +29,7 @@
 #include "channel_algorithm.hpp"
 #include "pixel.hpp"
 #include "gray.hpp"
+#include "gray_alpha.hpp"
 #include "rgb.hpp"
 #include "rgba.hpp"
 #include "cmyk.hpp"
@@ -110,6 +111,53 @@
 };
 
 /// \ingroup ColorConvert
+/// \brief Gray Alpha to RGBA
+template <>
+struct default_color_converter_impl<gray_alpha_t,rgba_t> {
+    template <typename P1, typename P2>
+    void operator()(const P1& src, P2& dst) const {
+        get_color(dst,red_t())  =
+            channel_convert<typename color_element_type<P2, red_t>::type>(get_color(src,gray_color_t()));
+        get_color(dst,green_t())=
+            channel_convert<typename color_element_type<P2, green_t>::type>(get_color(src,gray_color_t()));
+        get_color(dst,blue_t()) =
+            channel_convert<typename color_element_type<P2, blue_t>::type>(get_color(src,gray_color_t()));
+        get_color(dst,alpha_t()) =
+            channel_convert<typename color_element_type<P2, alpha_t>::type>(get_color(src,alpha_t()));
+    }
+};
+
+template <>
+struct default_color_converter_impl<gray_alpha_t,rgb_t> {
+    template <typename P1, typename P2>
+    void operator()(const P1& src, P2& dst) const {
+        get_color(dst,red_t())  =
+            channel_convert<typename color_element_type<P2, red_t>::type>(
+                channel_multiply(get_color(src,gray_color_t()),get_color(src,alpha_t()) ) 
+                );
+        get_color(dst,green_t())  =
+            channel_convert<typename color_element_type<P2, green_t>::type>(
+                channel_multiply(get_color(src,gray_color_t()),get_color(src,alpha_t()) ) 
+                );
+        get_color(dst,blue_t())  =
+            channel_convert<typename color_element_type<P2, blue_t>::type>(
+                channel_multiply(get_color(src,gray_color_t()),get_color(src,alpha_t()) ) 
+                );
+    }
+};
+
+template <>
+struct default_color_converter_impl<gray_alpha_t,gray_t> {
+    template <typename P1, typename P2>
+    void operator()(const P1& src, P2& dst) const {
+        get_color(dst,gray_color_t())  =
+            channel_convert<typename color_element_type<P2, gray_color_t>::type>(
+                channel_multiply(get_color(src,gray_color_t()),get_color(src,alpha_t()) ) 
+                );
+    }
+};
+
+/// \ingroup ColorConvert
 /// \brief Gray to CMYK
 template <>
 struct default_color_converter_impl<gray_t,cmyk_t> {
Index: bit_aligned_pixel_reference.hpp
===================================================================
--- bit_aligned_pixel_reference.hpp	(revision 42242)
+++ bit_aligned_pixel_reference.hpp	(working copy)
@@ -222,6 +222,49 @@
 template <typename B, typename C, typename L, bool M>  
 struct is_pixel<bit_aligned_pixel_reference<B,C,L,M> > : public mpl::true_{};
 
+namespace detail {
+
+	template <typename B, typename C, typename L, bool M>  
+	struct gen_chan_ref
+	{
+		typedef packed_dynamic_channel_reference<B,mpl::at_c<C,0>::type::value,M> type;
+	};
+
+	template<typename C,typename CMP, int Next, int Last>
+	struct is_homogeneous_impl;
+
+
+	template<typename C,typename CMP, int Last>
+	struct is_homogeneous_impl<C,CMP,Last,Last> : mpl::true_{};
+
+
+	template<typename C,typename CMP, int Next, int Last>
+	struct is_homogeneous_impl
+		: mpl::and_<
+			is_homogeneous_impl<C,CMP,Next+1,Last>,
+			is_same<CMP,typename mpl::at_c<C,Next>::type> 
+			> {};
+
+} // boost::gil::detail
+
+template <typename P>
+struct is_homogeneous;
+
+template <typename B, typename C, typename L, bool M>  
+struct is_homogeneous<bit_aligned_pixel_reference<B,C,L,M> > 
+	: detail::is_homogeneous_impl<C,typename mpl::at_c<C,0>::type,1,mpl::size<C>::type::value>
+{};
+
+template <typename B, typename C, typename L, bool M>  
+struct channel_type<bit_aligned_pixel_reference<B,C,L,M> > 
+	: boost::lazy_enable_if< 
+		is_homogeneous<bit_aligned_pixel_reference<B,C,L,M> >,
+		detail::gen_chan_ref<B,C,L,M>
+		>
+{};
+	
+	
+
 /////////////////////////////
 //  PixelBasedConcept
 /////////////////////////////
Index: extension/io/png_io_private.hpp
===================================================================
--- extension/io/png_io_private.hpp	(revision 42242)
+++ extension/io/png_io_private.hpp	(working copy)
@@ -34,15 +34,18 @@
 template <typename Cs> struct png_color_type {BOOST_STATIC_CONSTANT(int,color_type=0);};
 template<> struct png_color_type<gray_t> { BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY); };
 template<> struct png_color_type<rgb_t>  { BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB); };
+template<> struct png_color_type<gray_alpha_t>  { BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GA); };
 template<> struct png_color_type<rgba_t> { BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA); };
 
 template <typename Channel,typename ColorSpace> struct png_is_supported {BOOST_STATIC_CONSTANT(bool,value=false);};
 template <> struct png_is_supported<bits8,gray_t>  {BOOST_STATIC_CONSTANT(bool,value=true);};
+template <> struct png_is_supported<bits8,gray_alpha_t>  {BOOST_STATIC_CONSTANT(bool,value=true);};
 template <> struct png_is_supported<bits8,rgb_t>   {BOOST_STATIC_CONSTANT(bool,value=true);};
 template <> struct png_is_supported<bits8,rgba_t>  {BOOST_STATIC_CONSTANT(bool,value=true);};
 template <> struct png_is_supported<bits16,gray_t> {BOOST_STATIC_CONSTANT(bool,value=true);};
 template <> struct png_is_supported<bits16,rgb_t>  {BOOST_STATIC_CONSTANT(bool,value=true);};
 template <> struct png_is_supported<bits16,rgba_t> {BOOST_STATIC_CONSTANT(bool,value=true);};
+template <> struct png_is_supported<bits16,gray_alpha_t>  {BOOST_STATIC_CONSTANT(bool,value=true);};
 
 template <typename Channel> struct png_bit_depth {BOOST_STATIC_CONSTANT(int,bit_depth=sizeof(Channel)*8);};
 
@@ -52,18 +55,45 @@
     BOOST_STATIC_CONSTANT(int,bit_depth=0);
     BOOST_STATIC_CONSTANT(int,color_type=0);
 };
+template <typename BitField,bool Mutable>
+struct png_read_support_private<packed_dynamic_channel_reference<BitField,1,Mutable>,gray_t> {
+    BOOST_STATIC_CONSTANT(bool,is_supported=true);
+    BOOST_STATIC_CONSTANT(int,bit_depth=1);
+    BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY);
+};
+template <typename BitField,bool Mutable>
+struct png_read_support_private<packed_dynamic_channel_reference<BitField,2,Mutable>,gray_t> {
+    BOOST_STATIC_CONSTANT(bool,is_supported=true);
+    BOOST_STATIC_CONSTANT(int,bit_depth=2);
+    BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY);
+};
+template <typename BitField, bool Mutable>
+struct png_read_support_private<packed_dynamic_channel_reference<BitField,4,Mutable>,gray_t> {
+    BOOST_STATIC_CONSTANT(bool,is_supported=true);
+    BOOST_STATIC_CONSTANT(int,bit_depth=4);
+    BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY);
+};
 template <>
 struct png_read_support_private<bits8,gray_t> {
     BOOST_STATIC_CONSTANT(bool,is_supported=true);
     BOOST_STATIC_CONSTANT(int,bit_depth=8);
     BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY);
 };
+
 template <>
+struct png_read_support_private<bits8,gray_alpha_t> {
+    BOOST_STATIC_CONSTANT(bool,is_supported=true);
+    BOOST_STATIC_CONSTANT(int,bit_depth=8);
+    BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GA);
+};
+
+template <>
 struct png_read_support_private<bits8,rgb_t> {
     BOOST_STATIC_CONSTANT(bool,is_supported=true);
     BOOST_STATIC_CONSTANT(int,bit_depth=8);
     BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB);
 };
+
 template <>
 struct png_read_support_private<bits8,rgba_t> {
     BOOST_STATIC_CONSTANT(bool,is_supported=true);
@@ -88,6 +118,12 @@
     BOOST_STATIC_CONSTANT(int,bit_depth=16);
     BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGBA);
 };
+template <>
+struct png_read_support_private<bits16,gray_alpha_t> {
+    BOOST_STATIC_CONSTANT(bool,is_supported=true);
+    BOOST_STATIC_CONSTANT(int,bit_depth=16);
+    BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GA);
+};
 
 template <typename Channel,typename ColorSpace>
 struct png_write_support_private {
@@ -95,6 +131,25 @@
     BOOST_STATIC_CONSTANT(int,bit_depth=0);
     BOOST_STATIC_CONSTANT(int,color_type=0);
 };
+template <typename BitField,bool Mutable>
+struct png_write_support_private<packed_dynamic_channel_reference<BitField,1,Mutable>,gray_t> {
+    BOOST_STATIC_CONSTANT(bool,is_supported=true);
+    BOOST_STATIC_CONSTANT(int,bit_depth=1);
+    BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY);
+};
+template <typename BitField,bool Mutable>
+struct png_write_support_private<packed_dynamic_channel_reference<BitField,2,Mutable>,gray_t> {
+    BOOST_STATIC_CONSTANT(bool,is_supported=true);
+    BOOST_STATIC_CONSTANT(int,bit_depth=2);
+    BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY);
+};
+template <typename BitField, bool Mutable>
+struct png_write_support_private<packed_dynamic_channel_reference<BitField,4,Mutable>,gray_t> {
+    BOOST_STATIC_CONSTANT(bool,is_supported=true);
+    BOOST_STATIC_CONSTANT(int,bit_depth=4);
+    BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GRAY);
+};
+
 template <>
 struct png_write_support_private<bits8,gray_t> {
     BOOST_STATIC_CONSTANT(bool,is_supported=true);
@@ -108,6 +163,12 @@
     BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB);
 };
 template <>
+struct png_write_support_private<bits8,gray_alpha_t> {
+    BOOST_STATIC_CONSTANT(bool,is_supported=true);
+    BOOST_STATIC_CONSTANT(int,bit_depth=8);
+    BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GA);
+};
+template <>
 struct png_write_support_private<bits8,rgba_t> {
     BOOST_STATIC_CONSTANT(bool,is_supported=true);
     BOOST_STATIC_CONSTANT(int,bit_depth=8);
@@ -126,6 +187,12 @@
     BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_RGB);
 };
 template <>
+struct png_write_support_private<bits16,gray_alpha_t> {
+    BOOST_STATIC_CONSTANT(bool,is_supported=true);
+    BOOST_STATIC_CONSTANT(int,bit_depth=16);
+    BOOST_STATIC_CONSTANT(int,color_type=PNG_COLOR_TYPE_GA);
+};
+template <>
 struct png_write_support_private<bits16,rgba_t> {
     BOOST_STATIC_CONSTANT(bool,is_supported=true);
     BOOST_STATIC_CONSTANT(int,bit_depth=16);
@@ -191,16 +258,67 @@
            png_read_support_private<typename channel_type<View>::type,
                                     typename color_space_type<View>::type>::color_type!=color_type)
             io_error("png_read_view: input view type is incompatible with the image type");
-        
-        std::vector<pixel<typename channel_type<View>::type,
-                          layout<typename color_space_type<View>::type> > > row(width);
-        for(png_uint_32 y=0;y<height;++y) {
-            png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
-            std::copy(row.begin(),row.end(),view.row_begin(y));
+
+        if (little_endian() )
+        {   
+            if( png_read_support_private<typename channel_type<View>::type,
+                                      typename color_space_type<View>::type>::bit_depth == 16 )
+                png_set_swap(_png_ptr);
+            if( png_read_support_private<typename channel_type<View>::type,
+                                      typename color_space_type<View>::type>::bit_depth < 8 )
+                png_set_packswap(_png_ptr);
         }
+
+        read_rows(view,
+                mpl::int_<png_read_support_private<
+                    typename channel_type<View>::type,
+                    typename color_space_type<View>::type
+                    >::bit_depth>(),
+                mpl::int_<
+                    num_channels<typename View::value_type>::value
+                    >()
+                );
+
         png_read_end(_png_ptr,NULL);
     }
 
+    template<typename View, int BitDepth, int ChannelCount>
+    void read_rows(View const& view, 
+            mpl::int_<BitDepth> const&, 
+            mpl::int_<ChannelCount> const&, 
+            typename boost::enable_if_c<BitDepth == 8 || BitDepth == 16>::type *ptr = 0 )
+    {
+        std::vector<pixel<typename channel_type<View>::type,
+                          layout<typename color_space_type<View>::type> > > row(view.width());
+        for(int y=0;y<view.height();++y) {
+            png_read_row(_png_ptr,(png_bytep)&row.front(), NULL);
+            std::copy(row.begin(), row.end(), view.row_begin(y) );
+        }
+
+    }
+    template<typename View, int BitDepth, int ChannelCount>
+    void read_rows(View const& view, 
+            mpl::int_<BitDepth> const& , 
+            mpl::int_<ChannelCount> const& )
+    {
+        typedef bit_aligned_pixel_iterator<typename View::reference> iterator;
+        int c = ( view.width() * ChannelCount * BitDepth ) / (8);
+        int r =   view.width() * ChannelCount * BitDepth   - (8*c);
+        std::vector<unsigned char> row(c + (r!=0));
+        for(int y=0;y<view.height();++y) {
+            png_read_row(_png_ptr,png_bytep(&row.front()), NULL);
+            std::copy(
+                iterator(&row.front(),0),
+                r == 0
+                ? iterator(&row.back() + 1,r)
+                : iterator(&row.back(),r),
+                view.row_begin(y)
+                );
+        }
+
+    }
+
+
     template <typename Image>
     void read_image(Image& im) {
         im.recreate(get_dimensions());
@@ -219,75 +337,90 @@
     png_reader_color_convert(const char* filename,CC cc_in) : png_reader(filename),_cc(cc_in) {}
     png_reader_color_convert(const char* filename) : png_reader(filename) {}
     template <typename View>
-    void apply(const View& view) {
+    void apply(const View& view) 
+    {
         png_uint_32 width, height;
         int bit_depth, color_type, interlace_type;
         png_get_IHDR(_png_ptr, _info_ptr,
                      &width, &height,&bit_depth,&color_type,&interlace_type,
                      int_p_NULL, int_p_NULL);
         io_error_if(((png_uint_32)view.width()!=width || (png_uint_32)view.height()!= height),
-                    "png_reader_color_convert::apply(): input view size does not match PNG file size");
-        switch (color_type) {
+                "png_reader_color_convert::apply(): input view size does not match PNG file size");
+
+        if (little_endian() )
+        {   
+            if( png_read_support_private<typename channel_type<View>::type,
+                                      typename color_space_type<View>::type>::bit_depth == 16 )
+                png_set_swap(_png_ptr);
+            if( png_read_support_private<typename channel_type<View>::type,
+                                      typename color_space_type<View>::type>::bit_depth < 8 )
+                png_set_packswap(_png_ptr);
+        }
+
+        if(color_type == PNG_COLOR_TYPE_PALETTE)
+        {
+            color_type = PNG_COLOR_TYPE_RGB;
+            bit_depth = 8;
+            png_set_palette_to_rgb(_png_ptr);
+        }
+
+        if(png_get_valid(_png_ptr, _info_ptr,PNG_INFO_tRNS)) 
+        {
+            if( color_type == PNG_COLOR_TYPE_RGB )
+                color_type = PNG_COLOR_TYPE_RGBA;
+            else if( color_type == PNG_COLOR_TYPE_GRAY )
+                color_type = PNG_COLOR_TYPE_GA;
+
+            png_set_tRNS_to_alpha(_png_ptr);
+        }
+
+        typedef unsigned char  ba_type; // Use for bitaligned raw data
+        typedef bit_aligned_pixel_reference<ba_type,mpl::vector_c<int,1>,gray_layout_t,true> gray_1b;
+        typedef bit_aligned_pixel_reference<ba_type,mpl::vector_c<int,2>,gray_layout_t,true> gray_2b;
+        typedef bit_aligned_pixel_reference<ba_type,mpl::vector_c<int,4>,gray_layout_t,true> gray_4b;
+
+        switch (color_type) 
+        {
         case PNG_COLOR_TYPE_GRAY:
+            switch (bit_depth) 
+            {
+            case 1:  read_rows_bitaligned<gray_1b,ba_type,1,1>(view);
+                     break;
+            case 2:  read_rows_bitaligned<gray_2b,ba_type,1,2>(view);
+                     break;
+            case 4:  read_rows_bitaligned<gray_4b,ba_type,1,4>(view);
+                     break;
+            case 8:  read_rows<gray8_pixel_t>(view);
+                     break;
+            case 16: read_rows<gray16_pixel_t>(view);
+                     break;
+            default: io_error("png_reader_color_convert::apply(): unknown combination of color type and bit depth");
+            }
+            break;
+        case PNG_COLOR_TYPE_GA:
             switch (bit_depth) {
-            case 8: {
-                std::vector<gray8_pixel_t> row(width);
-                for(png_uint_32 y=0;y<height;++y) {
-                    png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
-                    std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<gray8_ref_t,typename View::value_type,CC>(_cc));
-                }
-                break;
-            }
-            case 16: {
-                std::vector<gray16_pixel_t> row(width);
-                for(png_uint_32 y=0;y<height;++y) {
-                    png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
-                    std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<gray16_ref_t,typename View::value_type,CC>(_cc));
-                }
-                break;
-            }
+            case 8:  read_rows<gray_alpha8_pixel_t>(view);
+                     break;
+            case 16: read_rows<gray_alpha16_pixel_t>(view);
+                     break;
             default: io_error("png_reader_color_convert::apply(): unknown combination of color type and bit depth");
             }
             break;
         case PNG_COLOR_TYPE_RGB:
             switch (bit_depth) {
-            case 8: {
-                std::vector<rgb8_pixel_t> row(width);
-                for(png_uint_32 y=0;y<height;++y) {
-                    png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
-                    std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgb8_ref_t,typename View::value_type,CC>(_cc));
-                }
-                break;
-            }
-            case 16: {
-                std::vector<rgb16_pixel_t> row(width);
-                for(png_uint_32 y=0;y<height;++y) {
-                    png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
-                    std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgb16_ref_t,typename View::value_type,CC>(_cc));
-                }
-                break;
-            }
+            case 8:  read_rows<rgb8_pixel_t>(view); 
+                     break;
+            case 16: read_rows<rgb16_pixel_t>(view);                         
+                     break;
             default: io_error("png_reader_color_convert::apply(): unknown combination of color type and bit depth");
             }
             break;
         case PNG_COLOR_TYPE_RGBA:
             switch (bit_depth) {
-            case 8: {
-                std::vector<rgba8_pixel_t> row(width);
-                for(png_uint_32 y=0;y<height;++y) {
-                    png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
-                    std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgba8_ref_t,typename View::value_type,CC>(_cc));
-                }
-                break;
-            }
-            case 16: {
-                std::vector<rgba16_pixel_t> row(width);
-                for(png_uint_32 y=0;y<height;++y) {
-                    png_read_row(_png_ptr,(png_bytep)&row.front(),NULL);
-                    std::transform(row.begin(),row.end(),view.row_begin(y),color_convert_deref_fn<rgba16_ref_t,typename View::value_type,CC>(_cc));
-                }
-                break;
-            }
+            case 8:  read_rows<rgba8_pixel_t>(view);
+                     break;
+            case 16: read_rows<rgba16_pixel_t>(view);
+                     break;
             default: io_error("png_reader_color_convert::apply(): unknown combination of color type and bit depth");
             }
             break;
@@ -295,11 +428,47 @@
         }
         png_read_end(_png_ptr,NULL);
     }
+    template <typename PixelT, typename View>
+    void read_rows( View & view )
+    {
+        std::vector<PixelT> row(view.width());
+        for(png_uint_32 y=0;y<view.height();++y) {
+            png_read_row(_png_ptr,png_bytep(&row.front()),NULL);
+            std::transform(
+                    row.begin(),row.end(),
+                    view.row_begin(y),
+                    color_convert_deref_fn<PixelT&,typename View::value_type,CC>(_cc)
+                    );
+        }
+    }
+
+    template <typename PixelRefT, typename BitFieldT, int Channels,int BitDepth, typename View>
+    void read_rows_bitaligned( View & view )
+    {
+        typedef bit_aligned_pixel_iterator<PixelRefT> iterator;
+
+        int c = ( view.width() * Channels * BitDepth ) / (sizeof(BitFieldT)*8);
+        int r =   view.width() * Channels * BitDepth   - (sizeof(BitFieldT)*8*c);
+
+        std::vector<BitFieldT> row(c + (r!=0));
+        for(png_uint_32 y=0;y<view.height();++y) {
+            png_read_row(_png_ptr,png_bytep(&row.front()),NULL);
+            std::transform( 
+                    iterator(&row.front(),0),
+                    (r == 0)
+                    ? iterator(&row.back() + 1,0)
+                    : iterator(&row.back(), r),
+                    view.row_begin(y),
+                    color_convert_deref_fn<PixelRefT,typename View::value_type,CC>(_cc)
+                    );
+        }
+    }
+
     template <typename Image>
-    void read_image(Image& im) {
-        im.recreate(get_dimensions());
-        apply(view(im));
-    }
+        void read_image(Image& im) {
+            im.recreate(get_dimensions());
+            apply(view(im));
+        }
 };
 
 
@@ -339,18 +508,63 @@
                      PNG_INTERLACE_NONE,
                      PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
         png_write_info(_png_ptr,_info_ptr);
-        if (little_endian() &&
-            png_write_support_private<typename channel_type<View>::type,
-                                      typename color_space_type<View>::type>::bit_depth>8)
-            png_set_swap(_png_ptr);
+        if (little_endian() )
+        {   
+            if( png_write_support_private<typename channel_type<View>::type,
+                                      typename color_space_type<View>::type>::bit_depth == 16 )
+                png_set_swap(_png_ptr);
+            if( png_write_support_private<typename channel_type<View>::type,
+                                      typename color_space_type<View>::type>::bit_depth < 8 )
+                png_set_packswap(_png_ptr);
+        }
+
+        write_rows(view,
+                mpl::int_<png_write_support_private<
+                    typename channel_type<View>::type,
+                    typename color_space_type<View>::type
+                    >::bit_depth>(),
+                mpl::int_<
+                    num_channels<typename View::value_type>::value
+                    >()
+                );
+
+        png_write_end(_png_ptr,_info_ptr);
+    }
+
+    template<typename View, int BitDepth, int ChannelCount>
+    void write_rows(View const& view, 
+            mpl::int_<BitDepth> const&, 
+            mpl::int_<ChannelCount> const&, 
+            typename boost::enable_if_c<BitDepth == 8 || BitDepth == 16>::type *ptr = 0 )
+    {
         std::vector<pixel<typename channel_type<View>::type,
                           layout<typename color_space_type<View>::type> > > row(view.width());
         for(int y=0;y<view.height();++y) {
             std::copy(view.row_begin(y),view.row_end(y),row.begin());
             png_write_row(_png_ptr,(png_bytep)&row.front());
         }
-        png_write_end(_png_ptr,_info_ptr);
+
     }
+    template<typename View, int BitDepth, int ChannelCount>
+    void write_rows(View const& view, 
+            mpl::int_<BitDepth> const& , 
+            mpl::int_<ChannelCount> const& )
+    {
+        typedef bit_aligned_pixel_iterator<typename View::reference> iterator;
+        int c = ( view.width() * ChannelCount * BitDepth ) / (8);
+        int r =   view.width() * ChannelCount * BitDepth   - (8*c);
+        std::vector<unsigned char> row(c + (r!=0));
+        for(int y=0;y<view.height();++y) {
+            std::copy(
+                view.row_begin(y),
+                view.row_end(y),
+                iterator(&row.front(),0)
+                );
+            png_write_row(_png_ptr,png_bytep(&row.front()));
+        }
+
+    }
+
 };
 
 } // namespace detail
