Logo Search packages:      
Sourcecode: f-spot version File versions  Download package

PixelBuffer.cs

using System;

namespace FSpot.Imaging {
      public enum PixelBufferDepth {
            UInt8 = 8,
            UInt16 = 16
      }

      public class UInt16Buffer : PixelBuffer {
            protected ushort [] data;

            public UInt16Buffer (int width, int height)
            {
                  this.width = width;
                  this.height = height;
                  this.nchannels = 3;

                  depth = PixelBufferDepth.UInt16;

                  rowstride = width * nchannels;

                  data = new ushort [width * height * nchannels];
            }

            public UInt16Buffer (Gdk.Pixbuf pixbuf, Cms.Profile profile)
            {
                  this.profile = profile;
                  width = pixbuf.Width;
                  height = pixbuf.Height;
                  this.nchannels = pixbuf.HasAlpha ? 4 : 3;
                  
                  depth = PixelBufferDepth.UInt16;

                  data = new ushort [width * height * nchannels];
                  
                  unsafe {
                        byte * src_pixels = (byte *) pixbuf.Pixels;
                        int src_stride = pixbuf.Rowstride;
                        int count = pixbuf.Width * nchannels;

                        for (int row = 0; row < height; row++) {
                              Fill8 (row, 0, src_pixels, row * src_stride, count);
                        }
                  }
            }

            public Cms.Format Format {
                  get {
                        return nchannels > 3 ? Cms.Format.Rgba16 : Cms.Format.Rgb16;
                  }
            }

            public unsafe void Fill8 (int i, int j, byte * src_data, int offset, int count)
            {
                  ushort * rowpix;
                  
                  fixed (ushort * pixels = &data [0]) {
                        rowpix = pixels + i * rowstride + j;
                        
                        for (int col = 0; col < count; col++) {
                              int val = src_data [col];
                              rowpix [col] = (ushort) (val << 8 & val);
                        }
                  }
            }

            public override void Fill8 (int row, int col, byte [] value, int start_offset, int len)
            {
                  unsafe {
                        fixed (byte * src_data = &value[0]) {
                              Fill8 (row, col, src_data, start_offset, len);
                        }
                  }
            }

            public override void Fill16 (int i, int j, byte [] src_data, int offset, int count, bool little)
            {
                  if (System.BitConverter.IsLittleEndian == little)
                        Fill16 (i, j, src_data, offset, count);
                  else
                        Fill16Swap (i, j, src_data, offset, count);
            }
            
            public void Fill16 (int i, int j, byte [] src_data, int offset, int count)
            { 
                  unsafe {
                        ushort * rowpix;

                        fixed (ushort * pixels = &data [0]) {
                              fixed (byte * bytes = &src_data [offset]) {
                                    ushort * src_pixels= (ushort *) bytes;

                                    rowpix = pixels + i * rowstride + j;

                                    for (int col = 0; col < count; col ++)
                                          rowpix [col] = src_pixels [col];
                              }
                        }
                  }
            }

            public void Fill16Swap (int i, int j, byte [] src_data, int offset, int count)
            {
                  unsafe {
                        ushort * rowpix;

                        fixed (ushort * pixels = &data [0]) {
                              fixed (byte * bytes = &src_data [offset]) {
                                    ushort * src_pixels = (ushort *) bytes;
                                    rowpix = pixels + i * rowstride + j;

                                    for (int col = 0; col < count; col ++)
                                          rowpix [col] = BitConverter.Swap (src_pixels [col]);
                              }
                        }
                  }
            }
            
            public override Gdk.Pixbuf ToPixbuf (Cms.Profile destination_profile)
            {
#if true //USE_LCMS
                  profile = Cms.Profile.CreateStandardRgb ();
                  Cms.Profile [] list = new Cms.Profile [] { profile, destination_profile };
                  Gdk.Pixbuf pixbuf = new Gdk.Pixbuf (Gdk.Colorspace.Rgb, false, 8, 
                                              width, height);
                  
                  Cms.Transform t = new Cms.Transform (list,
                                               Cms.Format.Rgb16,
                                               PixbufUtils.PixbufCmsFormat (pixbuf),
                                               Cms.Intent.Perceptual, 0x0);
                  
                  unsafe {
                        fixed (ushort * srcpix  = &data[0]) {
                              byte * destpix = (byte *) pixbuf.Pixels;
                              
                              for (int row = 0; row < height; row++)
                                    t.Apply ((IntPtr) (srcpix + row * rowstride),
                                           (IntPtr) (destpix + row * pixbuf.Rowstride),
                                           (uint)width);
                        }
                  }

                  return pixbuf;
#else
                  Gdk.Pixbuf pixbuf = new Gdk.Pixbuf (Gdk.Colorspace.Rgb, false, 8, 
                                              width, height);

                  unsafe {
                        fixed (ushort * src  = &data[0]) {
                              ushort * srcpix = src;
                              byte * destpix = (byte *) pixbuf.Pixels;
                              
                              for (int row = 0; row < height; row++) {
                                    for (int col = 0; col < width * nchannels; col++)
                                          destpix [col] = (byte) (srcpix [col] >> 8);
                                    
                                    srcpix += rowstride;
                                    destpix += pixbuf.Rowstride;
                              }
                        }
                  }

                  return pixbuf;
#endif
            }
      }

#if false
      public class UInt8Buffer : PixelBuffer {
            protected ushort [] data;
            
            
      }

      public class PixbufBuffer : PixelBuffer {
            protected Gdk.Pixbuf pixbuf;

            public PixbufBuffer (Gdk.Pixbuf pixbuf)
            {

            }
      }
#endif

      public abstract class PixelBuffer {
            protected int rowstride;
            protected int width;
            protected int height;
            protected int nchannels;
            protected PixelBufferDepth depth;
            protected Cms.Profile profile;

            protected PixelBuffer ()
            {

            }

            public int Width {
                  get {
                        return width;
                  }
            }

            public int Height {
                  get {
                        return height;
                  }
            }

            public abstract void Fill8 (int row, int col, byte [] value, int start_offset, int len);

            public abstract void Fill16 (int row, int col, byte [] data, int offset, int len, bool little);

            public abstract Gdk.Pixbuf ToPixbuf (Cms.Profile profile);
      }
}

Generated by  Doxygen 1.6.0   Back to index