Skip to content

Commit 1d1e422

Browse files
committed
Jpg: Fix parseECS not including first ECS byte (v_first) in return value.
Fixes regression reported in #215 (comment) Also fix follow-up error that `parseFrames`, `parseFramesSemiLazy` and `parseToFirstFrameHeader` incorrectly tried to parse beyond the `JpgEndOfImage`. Jpg: Fix `parseToFirstFrameHeader`
1 parent 73eacbb commit 1d1e422

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

src/Codec/Picture/Jpg/Internal/Types.hs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ parseECS = do
603603
-- so that we can set `consumed` properly, because this function is supposed
604604
-- to not consume the start of the segment marker (see code dropping the last
605605
-- byte of the previous chunk below).
606-
GetInternal.withInputChunks (v_first, B.empty) consumeChunk (L.fromChunks) (return . L.fromChunks)
606+
GetInternal.withInputChunks (v_first, B.empty) consumeChunk (L.fromChunks . (B.singleton v_first :)) (return . L.fromChunks . (B.singleton v_first :)) -- `v_first` also belongs to the returned BS
607607
where
608608
consumeChunk :: GetInternal.Consume (Word8, B.ByteString) -- which is: (Word8, B.ByteString) -> B.ByteString -> Either (Word8, B.ByteString) (B.ByteString, B.ByteString)
609609
consumeChunk (!v_chunk_start, !prev_chunk) !chunk =
@@ -772,6 +772,9 @@ parseFramesSemiLazy :: Get [JpgFrame]
772772
parseFramesSemiLazy = do
773773
kind <- get
774774
case kind of
775+
-- The end-of-image case needs to be here because `_ ->` default case below
776+
-- unconditionally uses `skipFrameMarker` which does not exist after `JpgEndOfImage`.
777+
JpgEndOfImage -> pure []
775778
JpgStartOfScan -> do
776779
scanHeader <- get
777780
remainingBytes <- getRemainingLazyBytes
@@ -806,10 +809,13 @@ parseFramesSemiLazy = do
806809
parseFrames :: Get [JpgFrame]
807810
parseFrames = do
808811
kind <- get
809-
mbFrame <- parseFrameOfKind kind
810-
skipFrameMarker
811-
remainingFrames <- parseFrames
812-
return $ maybeToList mbFrame ++ remainingFrames
812+
case kind of
813+
JpgEndOfImage -> pure []
814+
_ -> do
815+
mbFrame <- parseFrameOfKind kind
816+
skipFrameMarker
817+
remainingFrames <- parseFrames
818+
return $ maybeToList mbFrame ++ remainingFrames
813819

814820
-- | Parses forward, returning the first scan header encountered.
815821
--
@@ -822,6 +828,7 @@ parseToFirstFrameHeader :: Get (Maybe JpgFrameHeader)
822828
parseToFirstFrameHeader = do
823829
kind <- get
824830
case kind of
831+
JpgEndOfImage -> return Nothing
825832
JpgStartOfScan -> fail "parseToFirstFrameHeader: Encountered SOS frame marker before frame header that tells its dimensions"
826833
_ -> do
827834
mbFrame <- parseFrameOfKind kind

0 commit comments

Comments
 (0)