HDRUtils (empty) → 1.0.0
raw patch · 7 files changed
+582/−0 lines, 7 filesdep +arraydep +basedep +coloursetup-changed
Dependencies added: array, base, colour, containers, mtl, unix
Files
- Graphics/Image/PFS.hs +122/−0
- Graphics/Image/PFS/Internal.hs +76/−0
- Graphics/Image/PixelMap.hs +91/−0
- HDRUtils.cabal +52/−0
- LICENSE +24/−0
- Setup.hs +2/−0
- pfsapi.cxx +215/−0
+ Graphics/Image/PFS.hs view
@@ -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+
+ Graphics/Image/PFS/Internal.hs view
@@ -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
+ Graphics/Image/PixelMap.hs view
@@ -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+
+ HDRUtils.cabal view
@@ -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:
+ LICENSE view
@@ -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.+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ pfsapi.cxx view
@@ -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));+}++