id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc
1281	Wrong bounds computation in imageSurfaceGetPixels	guest	paolo	"r in imageSurfaceGetPixels is the stride of the surface, and therefore the number of bytes in one row (not the number of pixels).
Also, if I understand correctly, the +7 would have to go outside of the row computation to force rounding upwards.

Further, count in mkSurface is off by one.

Please see the following patch (file attachements not working):

{{{
diff -ru old/cairo-0.12.4/Graphics/Rendering/Cairo.hs new/cairo-0.12.4/Graphics/Rendering/Cairo.hs
--- old/cairo-0.12.4/Graphics/Rendering/Cairo.hs	2012-11-12 00:27:42.000000000 +0100
+++ new/cairo-0.12.4/Graphics/Rendering/Cairo.hs	2013-02-01 19:03:36.648095731 +0100
@@ -1813,15 +1813,10 @@
   when (pixPtr_==nullPtr) $ do
     fail ""imageSurfaceGetPixels: image surface not available""
   fmt <- imageSurfaceGetFormat pb
-  let bits = case fmt of
-               FormatARGB32 -> 32
-               FormatRGB24 -> 32
-               FormatA8 -> 8
-               FormatA1 -> 1
   h <- imageSurfaceGetHeight pb
   r <- imageSurfaceGetStride pb
   let pixPtr = castPtr pixPtr_
-  let bytes = h*((r*bits)+7) `div` 8
+      bytes = h * r
   return (mkSurfaceData pb pixPtr bytes)
 
 -- | An array that stores the raw pixel data of an image 'Surface'.
@@ -1833,7 +1828,7 @@
 
 mkSurfaceData :: Storable e => Surface -> Ptr e -> Int -> SurfaceData Int e
 mkSurfaceData pb (ptr :: Ptr e) size =
-  SurfaceData pb ptr (0, count) count
+  SurfaceData pb ptr (0, pred count) count
   where count = fromIntegral (size `div` sizeOf (undefined :: e))
 
 #if __GLASGOW_HASKELL__ < 605

}}}

The following should show the defect:

{{{
import Graphics.Rendering.Cairo
import Data.Array.IArray
import Data.Array.MArray (freeze)
import Data.Array.Unboxed (UArray)
import Data.Word

main :: IO ()
main = do
    (pixelData, stride) <- withImageSurface FormatRGB24 x y $ \surface -> do
        stride <- imageSurfaceGetStride surface
        renderWith surface $ do
            setSourceRGB 1 1 1
            paint
        pData <- imageSurfaceGetPixels surface >>= freeze :: IO (UArray Int Word8)
        return (pData, stride)
    putStrLn $ ""x : "" ++ show x ++ "" y : "" ++ show y ++ "" stride : "" ++ show stride ++ "" expected size : "" ++ show (y * stride) ++ "" or : "" ++ show (x * y * 4)
    print $ bounds pixelData
    putStrLn ""mistake shows here:""
    mapM_ print $ assocs pixelData
    where
    x = 10
    y = 10

}}}
"	defect	closed	normal	0.13.0	Cairo bindings	0.12.4	fixed		sven.mattsen@…
