diff --git a/Codec/Picture/Repa.hs b/Codec/Picture/Repa.hs
new file mode 100644
--- /dev/null
+++ b/Codec/Picture/Repa.hs
@@ -0,0 +1,252 @@
+{-# LANGUAGE EmptyDataDecls, FlexibleInstances, TypeSynonymInstances, MultiParamTypeClasses #-}
+module Codec.Picture.Repa
+       ( -- * Primitive types and operations
+         Img, imgData
+       , convertImage
+         -- * Generic interface
+       , readImage, decodeImage
+         -- * Monomorphic image decoding functions
+       , readImageRGBA, readImageRGB, readImageR, readImageG, readImageB
+       , decodeImageRGBA, decodeImageRGB, decodeImageR, decodeImageG, decodeImageB
+       -- * Image Representations (Phantom Types)
+       , RGBA, RGB, R, G, B
+       -- * Helper Functions (useful for OpenGL etc.) 
+       , toVector
+       , toForeignPtr
+       , reverseColorChannel
+       , flipHorizontally, flipVertically
+       -- * Internal Functionallity (exported for advanced uses)
+       , ToRGBAChannels(..)
+       ) where
+import qualified Data.Array.Repa as R
+import Data.Array.Repa ((:.), Array, (:.)(..), Z(..), DIM3, backpermute, extent)
+import qualified Codec.Picture as P
+import Codec.Picture hiding (readImage, decodeImage)
+import Codec.Picture.Types hiding (convertImage)
+import qualified Data.Vector.Storable as S
+import qualified Data.Vector.Unboxed as VU
+import Foreign.ForeignPtr
+import Data.Word
+import Control.Monad
+import Data.ByteString as B
+
+-- |An all-red image
+data R
+
+-- |An all-green image
+data G
+
+-- |An all-blue image
+data B
+
+-- |A 32-bit image with full red, green, blue and alpha channels.
+--
+-- The image is stored as Height x Width x ColorChannel.
+--
+-- The color channel is stored in RGBA order.  For the common OpenGL ordering
+-- users might want to use 'reverseColorChannel'.
+data RGBA
+
+-- |A 24-bit image with red, green and blue channels
+data RGB
+
+-- |@Img a@ is an image where the phantom type 'a' indicates the image format
+--
+-- All images are held in a three dimensional 'repa' array.  If the image
+-- format is only two dimensional (ex: R, G, or B) then the shape is @Z :. y :. x :. 1@.
+data Img a = Img { imgData :: Array DIM3 Word8 }
+
+-- |By default, the color channel for 'RGBA' indexes 0 -> R, 1 -> G, 2
+-- -> B, 3 -> A.  This is the AGBR byte ordering in OpenGL.  For
+-- rendering with OpenGL's RGBA PixelFormat be sure to call
+-- reverseColorChannel before converting to a Vector (or directly to
+-- bytestring via 'repa-bytestring').
+reverseColorChannel :: Img a -> Img a
+reverseColorChannel (Img r) = Img (R.backpermute e order r)
+  where
+  e@(Z :. row :. col :. z)  = R.extent r
+  order (Z :. r :. c :. z') = Z :. r :. c :. z - z' - 1
+
+readImageRGBA :: FilePath -> IO (Either String (Img RGBA))
+readImageRGBA = readImage
+
+readImageRGB :: FilePath -> IO (Either String (Img RGB))
+readImageRGB = readImage
+
+readImageB :: FilePath -> IO (Either String (Img B))
+readImageB = readImage
+
+readImageG :: FilePath -> IO (Either String (Img G))
+readImageG = readImage
+
+readImageR :: FilePath -> IO (Either String (Img R))
+readImageR = readImage
+
+decodeImageRGBA :: ByteString -> Either String (Img RGBA)
+decodeImageRGBA = decodeImage
+
+decodeImageRGB :: ByteString -> Either String (Img RGB)
+decodeImageRGB = decodeImage
+
+decodeImageR :: ByteString -> Either String (Img R)
+decodeImageR = decodeImage
+
+decodeImageG :: ByteString -> Either String (Img G)
+decodeImageG = decodeImage
+
+decodeImageB :: ByteString -> Either String (Img B)
+decodeImageB = decodeImage
+
+class DecodeImage a where
+  decodeImage :: ByteString -> Either String (Img a)
+
+instance DecodeImage RGBA where
+  decodeImage = decodeImageRGBA
+instance DecodeImage RGB where
+  decodeImage = decodeImageRGB
+instance DecodeImage R where
+  decodeImage = decodeImageR
+instance DecodeImage G where
+  decodeImage = decodeImageG
+instance DecodeImage B where
+  decodeImage = decodeImageB
+
+readImage :: DecodeImage a => FilePath -> IO (Either String (Img a))
+readImage f = liftM decodeImage (B.readFile f)
+
+-- | O(n)  returning (pointer, length, offset)
+toForeignPtr :: Img RGBA -> (ForeignPtr Word8, Int, Int)
+toForeignPtr = S.unsafeToForeignPtr . S.convert . R.toVector . imgData
+
+-- |Convert an 'Img' to a storable 'Vector', often useful for OpenGL
+-- and other C interfaces.  Notice the format of the data depends on
+-- the type of the 'Img a'. O(n)
+toVector :: Img a -> S.Vector Word8
+toVector (Img a) = S.convert (R.toVector a)
+
+-- Helper functions --
+getChannel :: Int -> PixelRGBA8 -> Word8
+getChannel 0 (PixelRGBA8 r g b a) = r
+getChannel 1 (PixelRGBA8 r g b a) = g
+getChannel 2 (PixelRGBA8 r g b a) = b
+getChannel _ (PixelRGBA8 r g b a) = a
+
+-- |For any of the JuicyPixel pixels, get the RGBA values
+getChan :: (ToRGBAChannels p) => Int -> p -> Word8
+getChan c = getChannel c . toRGBAChannels
+
+-- |For any of the JuicyPixel images, get a channel of a particular pixel
+getPixel :: (ToRGBAChannels p, Pixel p) => Int -> Int -> Int -> Image p -> Word8
+getPixel x y z p = getChan z (pixelAt p x y)
+
+-- Helper class and instances
+class ToRGBAChannels a where
+  toRGBAChannels :: a -> PixelRGBA8
+
+instance ToRGBAChannels PixelRGBA8 where
+  toRGBAChannels = id
+
+instance ToRGBAChannels PixelYCbCr8 where
+  toRGBAChannels = promotePixel . (id :: PixelRGB8 -> PixelRGB8) . convertPixel
+
+instance ToRGBAChannels PixelRGB8 where
+  toRGBAChannels = promotePixel
+
+instance ToRGBAChannels PixelYA8 where
+  toRGBAChannels = promotePixel
+  
+instance ToRGBAChannels Pixel8 where
+  toRGBAChannels = promotePixel
+
+zeroCopyConvert :: Int -> Image a -> Img b
+zeroCopyConvert cc (Image w h dat) =
+    let (ptr,off,len) = S.unsafeToForeignPtr dat
+        sh = Z :. h :. w :. cc
+    in if off == 0
+       then flipVertically . Img . R.unsafeFromForeignPtr sh   $  ptr
+       else flipVertically . Img . R.fromVector sh $ VU.convert $ dat
+
+-- Now we start the instances needing exported
+
+-- |Converts from 'JuicyPixels' type to the repa-based 'Img' type.
+class ConvertImage a b where
+  -- |Converts from 'JuicyPixels' type (Usually 'Image' or
+  -- 'DynamicImage' to the repa-based 'Img' type.
+  convertImage :: a -> Img b
+
+instance ConvertImage DynamicImage RGBA where
+  convertImage (ImageY8 i) = convertImage i
+  convertImage (ImageYA8 i) = convertImage i
+  convertImage (ImageRGB8 i) = convertImage i
+  convertImage (ImageRGBA8 i) = zeroCopyConvert 4 i
+  convertImage (ImageYCbCr8 i) = convertImage i
+  
+instance ConvertImage DynamicImage RGB where
+  convertImage (ImageY8 i) = convertImage i
+  convertImage (ImageYA8 i) = convertImage i
+  convertImage (ImageRGB8 i) = zeroCopyConvert 3 i
+  convertImage (ImageRGBA8 i) = convertImage i
+  convertImage (ImageYCbCr8 i) = convertImage i
+  
+instance ConvertImage DynamicImage R where
+  convertImage (ImageY8 i) = convertImage i
+  convertImage (ImageYA8 i) = convertImage i
+  convertImage (ImageRGB8 i) = convertImage i
+  convertImage (ImageRGBA8 i) = convertImage i
+  convertImage (ImageYCbCr8 i) = convertImage i
+  
+instance ConvertImage DynamicImage G where
+  convertImage (ImageY8 i) = convertImage i
+  convertImage (ImageYA8 i) = convertImage i
+  convertImage (ImageRGB8 i) = convertImage i
+  convertImage (ImageRGBA8 i) = convertImage i
+  convertImage (ImageYCbCr8 i) = convertImage i
+  
+instance ConvertImage DynamicImage B where
+  convertImage (ImageY8 i) = convertImage i
+  convertImage (ImageYA8 i) = convertImage i
+  convertImage (ImageRGB8 i) = convertImage i
+  convertImage (ImageRGBA8 i) = convertImage i
+  convertImage (ImageYCbCr8 i) = convertImage i
+
+instance (ToRGBAChannels a, Pixel a) => ConvertImage (Image a) RGBA where
+  convertImage p@(Image w h dat) =
+    let z = 4
+    in Img $ R.fromFunction (Z :. h :. w :. z) 
+                            (\(Z :. y :. x :. z') -> getPixel x y (z - z' - 1) p)
+  
+instance (ToRGBAChannels a, Pixel a) => ConvertImage (Image a) RGB where
+  convertImage p@(Image w h dat) =
+    let z = 3
+    in Img $ R.fromFunction (Z :. h :. w :. z)
+                            (\(Z :. y :. x :. z') -> getPixel x y (z' - z -1) p)
+
+instance (ToRGBAChannels a, Pixel a) => ConvertImage (Image a) R where
+  convertImage p@(Image w h dat) =
+    let z = 1
+    in Img $ R.fromFunction (Z :. h :. w :. z)
+                            (\(Z :. y :. x :. z) -> getPixel x y 0 p)
+       
+instance (ToRGBAChannels a, Pixel a) => ConvertImage (Image a) G where
+  convertImage p@(Image w h dat) =
+    let z = 1
+    in Img $ R.fromFunction (Z :. h :. w :. z)
+                            (\(Z :. y :. x :. z) -> getPixel x y 1 p)
+       
+instance (ToRGBAChannels a, Pixel a) => ConvertImage (Image a) B where
+  convertImage p@(Image w h dat) =
+    let z = 1
+    in Img $ R.fromFunction (Z :. h :. w :. z)
+                            (\(Z :. y :. x :. z) -> getPixel x y 2 p)
+
+flipVertically :: Img a -> Img a
+flipVertically (Img rp) = Img (backpermute e order rp)
+ where
+ e@(Z :. row :. col :. z) = extent rp
+ order (Z :. oldRow :. oldCol :. oldChan) = Z :. row - oldRow - 1 :. oldCol :. oldChan
+
+flipHorizontally :: Img a -> Img b
+flipHorizontally (Img rp) = Img (backpermute e order rp)
+ where
+ e@(Z :. row :. col :. z) = extent rp
+ order (Z :. oldRow :. oldCol :. oldChan) = Z :. oldRow :. col - oldCol - 1 :. oldChan
diff --git a/JuicyPixels-repa.cabal b/JuicyPixels-repa.cabal
new file mode 100644
--- /dev/null
+++ b/JuicyPixels-repa.cabal
@@ -0,0 +1,62 @@
+-- Juicy.Pixels.Interface.cabal auto-generated by cabal init. For
+-- additional options, see
+-- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.
+-- The name of the package.
+Name:                JuicyPixels-repa
+
+-- The package version. See the Haskell package versioning policy
+-- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for
+-- standards guiding when and how versions should be incremented.
+Version:             0.1
+
+-- A short (one-line) description of the package.
+Synopsis:            Convenience functions to obtain array representations of images.
+
+-- A longer description of the package.
+Description:         This wraps the Juicy.Pixels library to convert into 'Repa' and 
+                     'Data.Vector.Storable' formats.
+
+-- The license under which the package is released.
+License:             BSD3
+
+-- The file containing the license text.
+License-file:        LICENSE
+
+-- The package author(s).
+Author:              Thomas M. DuBuisson
+
+-- An email address to which users can send suggestions, bug reports,
+-- and patches.
+Maintainer:          Thomas.DuBuisson@gmail.com
+
+-- A copyright notice.
+-- Copyright:           
+
+Category:            Graphics
+
+Build-type:          Simple
+
+-- Extra files to be distributed with the package, such as examples or
+-- a README.
+-- Extra-source-files:  
+
+-- Constraint on the version of Cabal needed to build this package.
+Cabal-version:       >=1.6
+
+
+Library
+  -- Modules exported by the library.
+  Exposed-modules:     Codec.Picture.Repa
+  
+  -- Packages needed in order to build this package.
+  Build-depends:       base >= 4.0 && < 5, repa >= 2.1 && < 2.3
+                    , JuicyPixels >= 1.1 && < 1.2
+                    , vector >= 0.9 && < 0.10
+                    , bytestring >= 0.9 && < 0.10
+  
+  -- Modules not exported by this package.
+  -- Other-modules:       
+  
+  -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.
+  -- Build-tools:         
+  
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c)2012, Thomas M. DuBuisson
+
+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.
+
+    * Neither the name of Thomas M. DuBuisson nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"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
+OWNER OR CONTRIBUTORS 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
