Ticket #1281 (closed defect: fixed)

Opened 23 months ago

Last modified 22 months ago

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

Changed 23 months ago by guest

My contact info: sven.mattsen@…

The verification eMail never arrived.

Thanks,

Sven

Changed 23 months ago by dmwit

  • cc sven.mattsen@… added

Thanks for the report. Attachments should now work. Still looking into verification email problem (and current bug report as well, of course).

Changed 22 months ago by dmwit

  • status changed from new to closed
  • resolution set to fixed

Fixed. Thanks again for the report.

Note: See TracTickets for help on using tickets.