Ticket #1281 (closed defect: fixed)
Wrong bounds computation in imageSurfaceGetPixels
| Reported by: | guest | Owned by: | paolo |
|---|---|---|---|
| Priority: | normal | Milestone: | 0.13.0 |
| Component: | Cairo bindings | Version: | 0.12.4 |
| Keywords: | Cc: | sven.mattsen@… |
Description
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
Change History
Note: See
TracTickets for help on using
tickets.