Twinside / Juicy.Pixels

Haskell library to load & save pictures

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Corrupt JPEG data: premature end of data segment

mrkkrp opened this issue · comments

When saving a JPEG image with saveJpgImage 100, then opening it with GIMP, I'm getting a warning:

Corrupt JPEG data: premature end of data segment

I don't do anything funny, just save an image. Let me know if you cannot reproduce it, I'll investigate further.

Hi, I don't really have time to investigate right now, if you could digg, that would be great (sorry, I didn't have time to check your pull request also)

Do you have any sample image, all the test suite is saved at quality 100 and
I can't reproduce it with the GIMP 2.8.16

I'll create reproducing example when I have time, adding this to my todo list.

To reproduce execute the following:

{-# LANGUAGE RecordWildCards #-}

module Main (main) where

import Codec.Picture

main :: IO ()
main = do
  eimg <- readImage "pic.jpg"
  case eimg of
    Left _ -> undefined
    Right x ->
      ( saveJpgImage 100 "pic-result.jpg"
      . ImageRGB8
      . padImage
      . convertRGB8 ) x

-- | Pad image with white color so it's exactly 'desiredWidth' ×
-- 'desiredHeight' pixels in size.

padImage :: Image PixelRGB8 -> Image PixelRGB8
padImage img@Image {..} =
  let f x y  =
        if x < xstart || x >= xend || y < ystart || y >= yend
          then PixelRGB8 0xff 0xff 0xff
          else pixelAt img (x - xstart) (y - ystart)
      xstart = max 0 (desiredWidth - imageWidth) `quot` 2
      xend   = xstart + imageWidth
      ystart = max 0 (desiredHeight - imageHeight) `quot` 2
      yend   = ystart + imageHeight
  in generateImage f desiredWidth desiredHeight

-- | The width processed image should have.

desiredWidth :: Int
desiredWidth = 600

-- | The height processed image should have.

desiredHeight :: Int
desiredHeight = 600

On the following input file (for example):

pic

(Note that the image is absolutely normal.)

Then open in GIMP, that version you have should reproduce. Once you open resulting file you will see the following message at the bottom:

Corrupt JPEG data: premature end of data segment

It's possible that padImage is broken, but I don't see how (and how it can lead to such error message once it's saved).

Problem seems to be somewhere in colorspace conversion, rather than during saving an image as JPEG. Whenever I use hip to do the padding, that issue with gimp disappears.
Worth noting that, behind the scene, reading and saving of images is done using JuicyPixels, but color space conversion is part of hip and done over Double precision pixels.

module Main where

import Graphics.Image as I
import Graphics.Image.ColorSpace
import Graphics.Image.Types

main :: IO ()
main = do
  lena <- readImageRGB "lena.jpg"
  writeImageExact JPG [JPGQuality 100] "lena2.jpg" $
    I.map toWord8 $ toImageYCbCr $ padImage lena (600, 600)
  return ()

padImage :: Image VU RGB Double -> (Int, Int) -> Image VU RGB Double
padImage img d@(desiredHeight, desiredWidth) = makeImage d getPx
  where getPx (y, x) =
          if x < xstart || x >= xend || y < ystart || y >= yend
          then PixelRGB 1 1 1
          else index img (y - ystart, x - xstart)
        xstart = max 0 (desiredWidth - imageWidth) `quot` 2
        xend   = xstart + imageWidth
        ystart = max 0 (desiredHeight - imageHeight) `quot` 2
        yend   = ystart + imageHeight
        (imageHeight, imageWidth) = dims img

@mrkkrp : I ran your script, and GIMP doesn't whine with the generated image, same version of GIMP (2.8.16 (windows version if important)), and no warning message or anything :-/

@Twinside, I was able to reproduce the issue when I ran the script supplied by @mrkkrp on Ubuntu 16.04, gimp 2.8.16, ghc-7.10.3 and JuicyPixels-3.2.7
pic-result

Ok, I've reproduced it with jpegtran, part of libjpeg used by GIMP