diff --git a/Graphics/Image/PFS.hs b/Graphics/Image/PFS.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Image/PFS.hs
@@ -0,0 +1,122 @@
+{-# LANGUAGE BangPatterns #-}
+module Graphics.Image.PFS where
+
+import Foreign.C
+import Foreign
+import Graphics.Image.PFS.Internal
+import qualified Graphics.Image.PixelMap as P
+import qualified Data.Array.Storable as A
+import qualified Data.Map as M
+import Control.Monad
+import System.IO
+import System.Posix.IO
+import Control.Applicative
+
+data FPFrame = FPFrame {
+    tags :: [(String,String)]
+  , channelX :: A.StorableArray (Int,Int) CFloat
+  , channelY :: A.StorableArray (Int,Int) CFloat
+  , channelZ :: A.StorableArray (Int,Int) CFloat
+  , channels :: M.Map String (A.StorableArray (Int,Int) CFloat)
+  , width :: Int
+  , height :: Int
+}
+
+instance P.ImageData FPFrame where
+    toPixelMap (FPFrame t x y z cs w h) = P.PixelMap 
+        { P.width=w
+        , P.height=h
+        , P.pixels=M.fromList $ [("X", x), ("Y",y),("Z",z)] ++ M.toList cs
+        , P.colorspace=P.Ciea
+        , P.tags=t }
+    fromPixelMap (P.PixelMap t p w h P.Ciea) = FPFrame t (p M.! "X") (p M.! "Y") (p M.! "Z") M.empty w h        
+
+hReadFrame :: Handle -> IO FPFrame
+hReadFrame fileH = do 
+    fileFd <- fromIntegral <$> handleToFd fileH
+    fileh <- withCString "rb" $ \filemode -> fdopen fileFd filemode
+    domio <- pfs_newDOMIO
+    
+    frame <- pfs_DOMIOReadFrame domio fileh
+    tagctr <- pfs_FrameGetTags frame
+    tagitr <- pfs_TagContainerGetIterator tagctr
+    let loop !k = if (pfs_TagIteratorHasNext tagitr)==0 
+                    then do tagname <- pfs_TagIteratorGetNext tagitr 
+                            tagvalue <- pfs_TagContainerGetString tagctr tagname
+                            tagnameH <- peekCString tagname
+                            tagvalueH <- peekCString tagvalue
+                            loop ((tagnameH,tagvalueH):k) else return k
+    tagsl <- loop []
+    let w = fromIntegral $ pfs_FrameGetWidth frame
+        h = fromIntegral $ pfs_FrameGetHeight frame
+    (xc,yc,zc) <- alloca $ \x -> alloca $ \y -> alloca $ \z -> do
+        pfs_FrameGetXYZChannels frame x y z
+        xchanp <- peek x
+        ychanp <- peek y
+        zchanp <- peek z
+        xchan <- pfs_ChannelGetRawData xchanp
+        ychan <- pfs_ChannelGetRawData ychanp
+        zchan <- pfs_ChannelGetRawData zchanp
+        xchan' <- newForeignPtr_ xchan
+        ychan' <- newForeignPtr_ ychan
+        zchan' <- newForeignPtr_ zchan
+        xchanA <- A.unsafeForeignPtrToStorableArray xchan' ((0,0),(w,h))
+        ychanA <- A.unsafeForeignPtrToStorableArray ychan' ((0,0),(w,h))
+        zchanA <- A.unsafeForeignPtrToStorableArray zchan' ((0,0),(w,h))
+        return (xchanA,ychanA,zchanA)
+    pfs_deleteDOMIO domio
+
+    return $ FPFrame tagsl xc yc zc M.empty (w) (h)
+
+
+readFrameFromFile :: FilePath -> IO FPFrame
+readFrameFromFile path = do
+    fileh <- openFile path ReadMode
+    frame <- hReadFrame fileh
+    hClose fileh
+    return frame
+
+writeFrameToFile :: FilePath -> FPFrame -> IO ()
+writeFrameToFile path frame = do    
+    fileh <- openFile path WriteMode
+    hWriteFrame fileh frame
+    hClose fileh
+
+hWriteFrame :: Handle -> FPFrame -> IO ()
+hWriteFrame fileH frame = do
+    domio <- pfs_newDOMIO
+    fileFd <- fromIntegral <$> handleToFd fileH
+    fileh <- withCString "wb" $ \filemode -> fdopen fileFd filemode
+
+    frameh <- pfs_DOMIOCreateFrame domio (fromIntegral $ width frame) (fromIntegral $ height frame)
+    A.withStorableArray (channelX frame) $ \xchan -> A.withStorableArray (channelY frame) $ \ychan -> A.withStorableArray (channelZ frame) $ \zchan ->
+        alloca $ \xchanPP -> alloca $ \ychanPP -> alloca $ \zchanPP -> do
+            pfs_FrameCreateXYZChannels frameh xchanPP ychanPP zchanPP
+            xchanP <- peek xchanPP
+            ychanP <- peek ychanPP
+            zchanP <- peek zchanPP
+            ptrx <- pfs_ChannelGetRawData xchanP
+            copyBytes ptrx xchan ((width frame)*(height frame)*4) 
+            ptry <- pfs_ChannelGetRawData ychanP
+            copyBytes ptry ychan ((width frame)*(height frame)*4) 
+            ptrz <- pfs_ChannelGetRawData zchanP
+            copyBytes ptrz zchan ((width frame)*(height frame)*4) 
+        
+
+    forM_ (M.toList . channels $ frame) $ \(name,val) -> do 
+       channel <- withCString name $ \nameC -> pfs_FrameCreateChannel frameh nameC
+       ptr' <- pfs_ChannelGetRawData channel
+       A.withStorableArray val $ \ptr0 -> copyBytes ptr' ptr0 ((width frame)*(height frame)*4) 
+
+    tagctr <- pfs_FrameGetTags frameh
+    forM_ (tags frame) $ \(tag,value) -> withCString tag $ \tagC -> withCString value $ \valueC -> pfs_TagContainerSetString tagctr tagC valueC
+
+    pfs_DOMIOWriteFrame domio frameh fileh
+    pfs_deleteDOMIO domio
+
+getFrame :: IO FPFrame
+getFrame = hReadFrame stdin
+
+putFrame :: FPFrame -> IO ()
+putFrame = hWriteFrame stdout
+    
diff --git a/Graphics/Image/PFS/Internal.hs b/Graphics/Image/PFS/Internal.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Image/PFS/Internal.hs
@@ -0,0 +1,76 @@
+{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}
+
+module Graphics.Image.PFS.Internal where
+
+import Foreign
+import Foreign.C
+import Control.Monad
+
+data TagIterator
+data TagContainer
+data Channel
+data Array
+data ChannelIterator
+data Frame
+data DOMIO
+data FrameFile
+data FrameFileIterator
+data FILE
+
+type TagIteratorH = Ptr TagIterator
+type TagContainerH = Ptr TagContainer
+type ChannelH = Ptr Channel
+type ArrayH = Ptr Array
+type ChannelIteratorH = Ptr ChannelIterator
+type FrameH = Ptr Frame
+type DOMIOH = Ptr DOMIO
+type FrameFileH = Ptr FrameFile
+type FrameFileIteratorH = Ptr FrameFileIterator
+type FILEH = Ptr FILE
+
+foreign import ccall "pfs_TagIteratorGetNext" pfs_TagIteratorGetNext:: TagIteratorH -> IO CString
+foreign import ccall "pfs_TagIteratorHasNext" pfs_TagIteratorHasNext:: TagIteratorH -> CInt
+foreign import ccall "pfs_TagContainerGetString" pfs_TagContainerGetString :: TagContainerH -> CString -> IO CString 
+foreign import ccall "pfs_TagContainerSetString" pfs_TagContainerSetString :: TagContainerH -> CString -> CString -> IO ()
+foreign import ccall "pfs_TagContainerRemoveTag" pfs_TagContainerRemoveTag :: TagContainerH -> CString -> IO ()
+foreign import ccall "pfs_TagContainerGetIterator" pfs_TagContainerGetIterator :: TagContainerH -> IO TagIteratorH 
+foreign import ccall "pfs_Array2DGetCols" pfs_Array2DGetCols :: ArrayH -> CInt
+foreign import ccall "pfs_Array2DGetRows" pfs_Array2DGetRows :: ArrayH -> CInt
+foreign import ccall "pfs_Array2DGet" pfs_Array2DGet :: ArrayH -> CInt -> CInt -> CFloat
+foreign import ccall "pfs_Array2DSet" pfs_Array2DSet :: ArrayH -> CInt -> CInt -> CFloat -> IO CFloat
+foreign import ccall "pfs_Array1DGet" pfs_Array1DGet :: ArrayH -> CInt -> CFloat
+foreign import ccall "pfs_Array1DSet" pfs_Array1DSet :: ArrayH -> CInt -> CFloat -> IO CFloat
+foreign import ccall "pfs_ChannelGetWidth" pfs_ChannelGetWidth :: ChannelH -> CInt
+foreign import ccall "pfs_ChannelGetHeight" pfs_ChannelGetHeight :: ChannelH -> CInt
+foreign import ccall "pfs_ChannelGetName" pfs_ChannelGetName :: ChannelH -> CString
+foreign import ccall "pfs_ChannelGetTags" pfs_ChannelGetTags :: ChannelH -> IO TagContainerH
+foreign import ccall "pfs_ChannelGetRawData" pfs_ChannelGetRawData :: ChannelH -> IO (Ptr CFloat)
+foreign import ccall "pfs_ChannelIteratorGetNext" pfs_ChannelIteratorGetNext :: ChannelIteratorH -> IO ChannelH
+foreign import ccall "pfs_ChannelIteratorHasNext" pfs_ChannelIteratorHasNext :: ChannelIteratorH -> IO CInt
+foreign import ccall "pfs_FrameGetWidth" pfs_FrameGetWidth :: FrameH -> CInt
+foreign import ccall "pfs_FrameGetHeight" pfs_FrameGetHeight :: FrameH -> CInt
+foreign import ccall "pfs_FrameGetXYZChannels" pfs_FrameGetXYZChannels :: FrameH -> Ptr ChannelH -> Ptr ChannelH -> Ptr ChannelH -> IO ()
+foreign import ccall "pfs_FrameCreateXYZChannels" pfs_FrameCreateXYZChannels :: FrameH -> Ptr ChannelH -> Ptr ChannelH -> Ptr ChannelH -> IO ()
+foreign import ccall "pfs_FrameGetChannel" pfs_FrameGetChannel :: FrameH -> CString -> IO ChannelH
+foreign import ccall "pfs_FrameCreateChannel"pfs_FrameCreateChannel  :: FrameH -> CString -> IO ChannelH
+foreign import ccall "pfs_FrameRemoveChannel" pfs_FrameRemoveChannel :: FrameH -> ChannelH -> IO ()
+foreign import ccall "pfs_FrameGetChannelIterator" pfs_FrameGetChannelIterator :: FrameH -> IO ChannelIteratorH
+foreign import ccall "pfs_FrameGetTags" pfs_FrameGetTags ::FrameH -> IO TagContainerH
+foreign import ccall "pfs_newDOMIO" pfs_newDOMIO :: IO DOMIOH
+foreign import ccall "pfs_deleteDOMIO" pfs_deleteDOMIO :: DOMIOH -> IO ()
+foreign import ccall "pfs_DOMIOCreateFrame" pfs_DOMIOCreateFrame :: DOMIOH -> CInt -> CInt -> IO FrameH
+foreign import ccall "pfs_DOMIOWriteFrame" pfs_DOMIOWriteFrame :: DOMIOH -> FrameH -> FILEH -> IO ()
+foreign import ccall "pfs_DOMIOReadFrame" pfs_DOMIOReadFrame :: DOMIOH -> FILEH -> IO FrameH
+foreign import ccall "pfs_DOMIOFreeFrame" pfs_DOMIOFreeFrame :: DOMIOH -> FrameH -> IO ()
+foreign import ccall "pfs_newFrameFile" pfs_newFrameFile :: FILEH -> CString -> IO FrameFileH
+foreign import ccall "pfs_FrameFileGetFileHandle" pfs_FrameFileGetFileHandle :: FrameFileH -> FILEH
+foreign import ccall "pfsFrameFileGetFileName" pfsFrameFileGetFileName :: FrameFileH -> CString
+foreign import ccall "pfs_newFrameFileIterator" pfs_newFrameFileIterator :: Ptr CInt -> Ptr CString -> CString -> CString -> FILEH -> CString -> Ptr () -> IO FrameFileIteratorH
+foreign import ccall "pfs_FrameFileIteratorGetNextFrameFile" pfs_FrameFileIteratorGetNextFrameFile :: FrameFileIteratorH -> IO FrameFileH
+foreign import ccall "pfs_FrameFileIteratorCloseFrameFile" pfs_FrameFileIteratorCloseFrameFile :: FrameFileH -> IO ()
+foreign import ccall "pfs_freeChannelIterator" pfs_freeChannelIterator :: ChannelIteratorH -> IO ()
+foreign import ccall "pfs_freeTagIterator" pfs_freeTagIterator :: TagIteratorH -> IO ()
+
+foreign import ccall "fopen" fopen :: CString -> CString -> IO FILEH
+foreign import ccall "fclose" fclose :: FILEH -> IO ()
+foreign import ccall "fdopen" fdopen :: CInt -> CString -> IO FILEH
diff --git a/Graphics/Image/PixelMap.hs b/Graphics/Image/PixelMap.hs
new file mode 100644
--- /dev/null
+++ b/Graphics/Image/PixelMap.hs
@@ -0,0 +1,91 @@
+module Graphics.Image.PixelMap where
+
+import Data.Colour
+import Data.Colour.Names (black)
+import qualified Data.Colour.SRGB as SRGB
+import qualified Data.Colour.SRGB.Linear as SRGBLinear
+import qualified Data.Colour.CIE as CIE
+import qualified Data.Colour.RGBSpace as RGB
+import qualified Data.Array.Storable as A
+import qualified Data.Map as M
+import Foreign.C
+
+type Channel = A.StorableArray (Int,Int) Float
+
+data PixelMap = PixelMap {
+     tags :: [(String,String)]
+  ,  pixels :: M.Map String (A.StorableArray (Int,Int) CFloat)
+  ,  width :: Int
+  ,  height :: Int
+  ,  colorspace :: ColourSpace 
+}
+
+class ImageData a where
+    toPixelMap :: a -> PixelMap
+    fromPixelMap :: PixelMap -> a
+
+data ColourSpace = 
+    Ciea 
+  | Rgba (RGB.RGBSpace CFloat) 
+  | Srgba 
+  | SrgbaLinear
+
+ixHelper :: M.Map String (A.StorableArray (Int,Int) CFloat) ->  String ->  String  -> String -> (CFloat -> CFloat -> CFloat -> Colour CFloat) -> (Int,Int) -> IO (AlphaColour CFloat)
+ixHelper pxs chan0 chan1 chan2 cofun ix = do
+    a <- (pxs M.! chan0) `A.readArray` ix 
+    b <- (pxs M.! chan1) `A.readArray` ix    
+    c <- (pxs M.! chan2) `A.readArray` ix
+    alpha <- maybe (return 1) (`A.readArray` ix) (M.lookup "A" pxs)
+    return $ cofun a b c `withOpacity` alpha      
+
+(!!) :: PixelMap -> (Int, Int) -> IO (AlphaColour CFloat)
+(PixelMap _ pxs _ _ Ciea) !! ix = ixHelper pxs "X" "Y" "Z" CIE.cieXYZ ix 
+(PixelMap _ pxs _ _ (Rgba space)) !! ix = ixHelper pxs "R" "G" "B" (RGB.rgbUsingSpace space) ix
+(PixelMap _ pxs _ _ Srgba) !! ix = ixHelper pxs "R" "G" "B" SRGB.sRGB ix
+(PixelMap _ pxs _ _ SrgbaLinear) !! ix = ixHelper pxs "R" "G" "B" SRGBLinear.rgb ix
+
+(!/) :: PixelMap -> (Int,Int,String) -> IO CFloat
+(PixelMap _ pxs _ _ _) !/ (r,c,ch) = maybe (return 1) (`A.readArray` (r,c)) (M.lookup ch pxs)    
+
+(!/=) :: (CFloat -> IO ()) -> CFloat -> IO ()
+a !/= b = a b
+
+refChan :: PixelMap -> (Int,Int) -> String -> CFloat -> IO ()
+refChan mp ix ch = A.writeArray (pixels mp M.! ch) ix
+
+(!=) :: (AlphaColour CFloat -> IO ()) -> AlphaColour CFloat -> IO ()
+a != b = a b
+
+refPixel :: PixelMap -> (Int,Int) -> AlphaColour CFloat -> IO ()
+refPixel (PixelMap _ pxs _ _ Ciea) ix c = do
+    let (x,y,z) = CIE.toCIEXYZ $ (1/a) `darken` (c `Data.Colour.over` black)
+        a = alphaChannel c
+    A.writeArray (pxs M.! "X") ix $ x
+    A.writeArray (pxs M.! "Y") ix $ y
+    A.writeArray (pxs M.! "Z") ix $ z
+    A.writeArray (pxs M.! "A") ix $ a 
+    
+refPixel (PixelMap _ pxs _ _ (Rgba space)) ix c = do
+    let (RGB.RGB r g b) = RGB.toRGBUsingSpace space $ (1/a) `darken` (c `Data.Colour.over` black)
+        a = alphaChannel c
+    A.writeArray (pxs M.! "R") ix r
+    A.writeArray (pxs M.! "G") ix g        
+    A.writeArray (pxs M.! "B") ix b
+    A.writeArray (pxs M.! "A") ix a
+    
+refPixel (PixelMap _ pxs _ _ Srgba) ix c =  do
+    let (SRGB.RGB r g b) = SRGB.toSRGB $ (1/a) `darken` (c `Data.Colour.over` black)
+        a = alphaChannel c
+    A.writeArray (pxs M.! "R") ix r
+    A.writeArray (pxs M.! "G") ix g        
+    A.writeArray (pxs M.! "B") ix b
+    A.writeArray (pxs M.! "A") ix a
+    
+refPixel (PixelMap _ pxs _ _ SrgbaLinear) ix c =  do
+    let (SRGBLinear.RGB r g b) = SRGBLinear.toRGB $ (1/a) `darken` (c `Data.Colour.over` black)
+        a = alphaChannel c
+    A.writeArray (pxs M.! "R") ix r
+    A.writeArray (pxs M.! "G") ix g        
+    A.writeArray (pxs M.! "B") ix b
+    A.writeArray (pxs M.! "A") ix a
+
diff --git a/HDRUtils.cabal b/HDRUtils.cabal
new file mode 100644
--- /dev/null
+++ b/HDRUtils.cabal
@@ -0,0 +1,52 @@
+name: HDRUtils 
+version: 1.0.0
+cabal-version: >=1.2
+build-type: Simple
+license: BSD3
+license-file: LICENSE
+copyright: 2009 Jeff Heard
+maintainer: J.R. Heard
+build-depends: array -any, base == 4.1.0.0, containers -any, mtl -any, colour > 2.2.0, unix <= 2.3.2.0
+stability:
+homepage: http://vis.renci.org/jeff/pfs
+package-url: 
+bug-reports:
+synopsis: Utilities for reading, manipulating, and writing HDR images
+description: PFS is a library for manipulating Portable Floating-point Streams, an interchange
+ format for high-dynamic range images.  You will need pfstools for this library to work properly.
+ pfstools can be found at http://pfstools.sourceforge.net/
+             
+category: Graphics
+author: J.R. Heard
+tested-with:
+data-files:
+data-dir: ""
+extra-source-files:
+extra-tmp-files:
+exposed-modules: Graphics.Image.PFS.Internal
+                 Graphics.Image.PFS
+                 Graphics.Image.PixelMap
+                 
+exposed: True
+buildable: True
+build-tools:
+cpp-options:
+cc-options:
+ld-options:
+pkgconfig-depends:
+frameworks:
+c-sources: pfsapi.cxx
+extensions:
+extra-libraries: pfs-1.2
+extra-lib-dirs:
+includes: 
+install-includes:
+include-dirs: .
+hs-source-dirs: .
+other-modules:
+ghc-prof-options:
+ghc-shared-options:
+ghc-options: 
+hugs-options:
+nhc98-options:
+jhc-options:
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,24 @@
+Copyright 2008, Renaissance Computing Institute.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+ 
+- Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+ 
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/pfsapi.cxx b/pfsapi.cxx
new file mode 100644
--- /dev/null
+++ b/pfsapi.cxx
@@ -0,0 +1,215 @@
+#include "pfsapi.h"
+#include <pfs-1.2/pfs.h>
+
+using namespace pfs;
+
+const char* pfs_TagIteratorGetNext(pfs_TagIterator self) 
+{
+    return ((TagIterator*)self)->getNext();
+}
+
+int pfs_TagIteratorHasNext(pfs_TagIterator self)
+{
+    return ((TagIterator*)self)->hasNext();
+}
+
+const char *pfs_TagContainerGetString(pfs_TagContainer self, const char* tagName) 
+{
+    return ((TagContainer*) self)->getString(tagName);
+}
+
+void pfs_TagContainerSetString(pfs_TagContainer self, const char* tagName, const char* tagValue) 
+{
+    ((TagContainer*) self)->setString(tagName, tagValue);
+}
+
+void pfs_TagContainerRemoveTag(pfs_TagContainer self, const char* tagName) 
+{
+    ((TagContainer*) self)->removeTag(tagName);
+}
+
+pfs_TagIterator pfs_TagContainerGetIterator (pfs_TagContainer self) 
+{
+    TagIteratorPtr iter = (((TagContainer*) self)->getIterator());
+    TagIterator *ptr = iter.release();
+    return (void*) ptr; 
+}
+
+void pfs_freeTagIterator(pfs_TagIterator titer) {
+    delete (TagIteratorPtr*) titer;
+}
+
+int pfs_Array2DGetCols(pfs_Array self) 
+{
+    return ((Array2D*)self)->getCols();
+}
+
+int pfs_Array2DGetRows(pfs_Array self)
+{
+    return ((Array2D*)self)->getRows();
+}
+
+float pfs_Array2DGet(pfs_Array self, int col, int row) 
+{
+    return ((Array2D*)self)->operator()(col,row);
+}
+
+float pfs_Array2DSet(pfs_Array self, int col, int row, float value)
+{
+    ((Array2D*)self)->operator()(col,row) = value;
+    return value;
+}
+
+float pfs_Array1DGet(pfs_Array self, int ix) 
+{
+    return    (*((Array2D*)self))(ix);
+}
+float pfs_Array1DSet(pfs_Array self, int ix, float value)
+{
+    (*((Array2D*)self))(ix) = value;
+    return value;
+}
+
+int pfs_ChannelGetWidth(pfs_Channel self) 
+{
+    return ((Channel*)self)->getWidth();
+}
+
+int pfs_ChannelGetHeight(pfs_Channel self) 
+{
+    return ((Channel*)self)->getHeight();
+}
+const char *pfs_ChannelGetName(pfs_Channel self) 
+{
+    return ((Channel*)self)->getName();
+}
+pfs_TagContainer pfs_ChannelGetTags(pfs_Channel self) 
+{
+    return (void*)(((Channel*)self)->getTags());
+}
+
+float* pfs_ChannelGetRawData(pfs_Channel self) 
+{
+    return ((Channel*)self)->getRawData();
+}
+
+pfs_Channel pfs_ChannelIteratorGetNext(pfs_ChannelIterator self) 
+{
+    return (void*)(((ChannelIterator*)self)->getNext());
+}
+
+int pfs_ChannelIteratorHasNext(pfs_ChannelIterator self)
+{
+    return ((ChannelIterator*)self)->hasNext();
+}
+
+int pfs_FrameGetWidth(pfs_Frame self) 
+{
+    return ((Frame*)self)->getWidth();
+}
+int pfs_FrameGetHeight(pfs_Frame self) 
+{
+    return ((Frame*)self)->getHeight();
+}
+
+void pfs_FrameGetXYZChannels(pfs_Frame self, pfs_Channel *xout, pfs_Channel *yout, pfs_Channel *zout)
+{
+    Channel *x, *y, *z;
+    ((Frame*)self)->getXYZChannels(x,y,z);
+    *xout = (void*)x;
+    *yout = (void*)y;
+    *zout = (void*)z;
+}
+
+void pfs_FrameCreateXYZChannels(pfs_Frame self, pfs_Channel *xout, pfs_Channel *yout, pfs_Channel *zout)
+{
+    Channel *x, *y, *z;
+    ((Frame*)self)->createXYZChannels(x,y,z);
+    *xout = (void*)x;
+    *yout = (void*)y;
+    *zout = (void*)z;
+}
+
+pfs_Channel pfs_FrameGetChannel(pfs_Frame self, const char* name)
+{
+    return (void*)(((Frame*)self)->getChannel(name));
+}
+
+pfs_Channel pfs_FrameCreateChannel(pfs_Frame self, const char* name)
+{
+    return (void*)(((Frame*)self)->createChannel(name));
+}
+
+void pfs_FrameRemoveChannel(pfs_Frame self, pfs_Channel channel) 
+{
+    ((Frame*)self)->removeChannel((Channel*)channel);
+}
+
+pfs_ChannelIterator pfs_FrameGetChannelIterator (pfs_Frame self) 
+{
+    ChannelIteratorPtr iter = (((Frame*) self)->getChannelIterator());
+    ChannelIterator *ptr = iter.release();
+    return (void*) ptr; 
+}
+
+void pfs_freeChannelIterator(pfs_ChannelIterator i) { 
+    delete (ChannelIteratorPtr*)i;
+}
+
+pfs_TagContainer pfs_FrameGetTags(pfs_Frame self)
+{
+    return (void*)(((Frame*)self)->getTags());
+}
+
+pfs_DOMIO pfs_newDOMIO() {
+    return (void*)(new DOMIO());
+}
+
+void pfs_deleteDOMIO(pfs_DOMIO self) {
+    delete ((DOMIO*)self);
+}
+
+pfs_Frame pfs_DOMIOCreateFrame(pfs_DOMIO self, int width, int height) {
+    return (void*)(((DOMIO*)self)->createFrame(width,height));
+}
+
+pfs_Frame pfs_DOMIOReadFrame(pfs_DOMIO self, FILE* inputStream) {
+    return (void*)(((DOMIO*)self)->readFrame(inputStream));
+}
+
+void pfs_DOMIOWriteFrame(pfs_DOMIO self, pfs_Frame frame, FILE* outputStream) {
+    ((DOMIO*)self)->writeFrame((Frame*)frame, outputStream);
+}
+
+void pfs_DOMIOFreeFrame(pfs_DOMIO self, pfs_Frame frame) {
+    ((DOMIO*)self)->freeFrame((Frame*)frame);
+}
+
+pfs_FrameFile pfs_newFrameFile(FILE *fh, const char *fileName) {
+    return (void*)(new FrameFile(fh,fileName));
+}
+
+FILE *pfs_FrameFileGetFileHandle(pfs_FrameFile self) {
+    return ((FrameFile*)self)->fh;
+}
+
+const char *pfsFrameFileGetFileName(pfs_FrameFile self) {
+    return ((FrameFile*)self)->fileName;
+}
+
+pfs_FrameFileIterator pfs_newFrameFileIterator(int *argc, char **argv, const char *fopenMode, const char *fileNamePrefix, FILE *stdinout, const char *optstring, const void *getopt_long) 
+{
+    return (void*)( new FrameFileIterator(*argc,argv,fopenMode,fileNamePrefix,stdinout,optstring,(option *)getopt_long));
+}
+
+pfs_FrameFile pfs_FrameFileIteratorGetNextFrameFile(pfs_FrameFileIterator self)
+{
+    return (void*) new FrameFile((((FrameFileIterator*)self)->getNextFrameFile()));
+}
+
+void pfs_FrameFileIteratorCloseFrameFile(pfs_FrameFileIterator self, pfs_FrameFile frameFile) 
+{
+    ((FrameFileIterator*)self)->closeFrameFile(*((FrameFile*)frameFile));
+}
+
+
