2

Distorted GIF

I have a few images that were converted using Imagemagick and its interlaced operation. These were the animated GIF images. The issue is that, while converting, the images have distorted and I do not have original images with me as it was the previous developer who did the wonderful thing. The GIF is no more animating and each frame has 4 copies of the same frame with decreasing sizes. I have not worked much on Imagemagick before.

Is there any way I can restore the original image from the distorted version?

The command used was:

convert <old-file.gif> -interlace plane <new-file.gif>

Thanks

Nerve
  • 6,463
  • 4
  • 29
  • 29
  • add the image example so we can look at it if it is really wrong or not (and see if it contains what it should or not) ... also this is GIF87a or GIF89a ... with what are you previewing? have you tried different GIF viewer? – Spektre Nov 09 '15 at 08:09
  • @Spektre Thanks for replying. I have added the image. – Nerve Nov 09 '15 at 09:36
  • Added repiared image and some links + info to answer. If you need the auxiliary extensions feed too then you need to process it by yourself. Also timing can be a bit off from the original ... – Spektre Nov 09 '15 at 14:01

1 Answers1

3

interlaced GIF images are stored as 4 separated images

  1. containing every 8th line of image (1/8 of size)
  2. containing every missing 4th line of image (1/8 of size)
  3. containing every missing even line of image (1/4 of size)
  4. containing every odd line of image (1/2 of size)

This is done so the image can be seen while loading through slow Internet connection ... increasing details with every new chunk...

So if your image looks like 4 very similar images then the result is OK you just wrongly decode it or the GIF has not set the Interlaced flag.

If your file does not contain the animation frames anymore then you are out of luck but if they are there and not rendering then check the GIF end of file is not misplaced or check the flags they could be screwed up... Have you tried different GIF viewer (some are buggy)

[Edit1] after decoding your GIF

You got GIF89a and you are missing interlaced flags in each frame. So the image is interlaced correctly but the viewer thinks it is not interlaced at all ... You need to mark interlaced flag in each frame header.

struct _img // this is image frame header
    {
    // Logical Image Descriptor
    BYTE Separator;         /* Image Descriptor identifier 0x2C */
    WORD x0;                /* X position of image on the display */
    WORD y0;                /* Y position of image on the display */
    WORD xs;                /* Width of the image in pixels */
    WORD ys;                /* Height of the image in pixels */
    BYTE Packed;            /* Image and Color Table Data Information */
    } img;

img.Packed|=64; // this will set the interlaced flag

To do that you need to decode/stream copy the GIF which is not that easy as it sounds.

see:

Here the result of frames copy + deinterlace + interlaced encode (skipping control/info/auxiliary feeds ...)

repaired image

Community
  • 1
  • 1
Spektre
  • 49,595
  • 11
  • 110
  • 380
  • Thanks so much for this. I have started working on a script to do this as I have hundreds of such images. So, I have to read in the byte of data from image and try to find the interlace Bit on each frame and flip it. Please correct me if I am wrong. – Nerve Nov 18 '15 at 13:57
  • @Nerve yes exactly ... look at the link [How to find where does Image Block start in GIF images?] from my answer there is C++ source I use for processing GIFs ... – Spektre Nov 18 '15 at 15:34
  • I have been able to find the interlacing bit for the first frame. The first frames becomes perfect after this. However, I still can't find them for other frames. I am not able to determine how to find the frames in the image data block. Can you help? – Nerve Nov 21 '15 at 12:36
  • @Nerve you need to process/skp the frame LZW data similar to skipping extensions blocks and when ecnd of frame detected search for next frame in the same manner as the first (except there is no global palette anymore). All chunks have first byte the chunk length and then the data follows so skip it ... if found terminator chunk (size=0) you are at the end of image frame. If I remember correctly before first chunk of image data there is 1 BYTE telling how many bits are starting with. – Spektre Nov 21 '15 at 16:47
  • btw more than half of your image are auxiliary control feeds the repaired I posted in answer is without them (little less then half of your original gif size )... – Spektre Nov 21 '15 at 16:50
  • Hey, thank you so much. I have been able to fix the issue. I am planning to stream line the code and push it to a Gist. I will make an API to access frames / images as raw bytes so they can be easily manipulated without any tool. Will post a link here once done. I code mostly in Ruby language (tacky!). – Nerve Nov 21 '15 at 21:15