GIFs and the Color black

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

GIFs and the Color black

darth-cheney
Hi all,

I've noticed that in the current implementation of GIFReadWriter, we cannot faithfully reproduce the color black when writing it and reading it back in. Quick note: before I rewrote large parts of the GIF stuff in Pharo a while back, it had the same implementation as Squeak. But both then and now, Pharo does not have the problem that I am describing. This leads me to believe that the problem is actually at some low level that I'm not equipped to understand.

I'm hoping that the collective wisdom on this list might have some ideas. I'm thinking there's something going on with color mapping and Bitmaps (maybe color depths and conversions as well?) which I don't understand very well. On the other hand, I do have a good understanding of the GIF format since I worked on it. The LZW compression is a real nightmare, and even in my Pharo rewrite I had to keep the LZW encoding portions from the original implementation.

The following code, when done in a workspace, will clearly demonstrate the issue:
```
blackForm := Form extent: 100@100.
blackForm getCanvas fillColor: Color black.

"Write to a bytestream"
out := WriteStream on: ByteArray new.
writer := GIFReadWriter on: out.
writer nextPutImage: blackForm.
writer close.

"Read from the bytestream"
in := ReadStream on: out contents.
reader := GIFReadWriter on: in.
result := reader nextImage.

(result colorAt: 50@50) inspect.
```

The resulting color is not what we expect (Color black). It is (Color r: 0.0 g: 0.0 b: 0.004)

Any ideas what's going on?

--
Eric


Reply | Threaded
Open this post in threaded view
|

Re: GIFs and the Color black

Karl Ramberg
I think Color r: 0.0 g: 0.0 b: 0.0 was/is reserved for transparency in forms with less than 32 bit depth, eg. no alpha channel

Best,
Karl



On Sun, Aug 9, 2020 at 4:55 AM Eric Gade <[hidden email]> wrote:
Hi all,

I've noticed that in the current implementation of GIFReadWriter, we cannot faithfully reproduce the color black when writing it and reading it back in. Quick note: before I rewrote large parts of the GIF stuff in Pharo a while back, it had the same implementation as Squeak. But both then and now, Pharo does not have the problem that I am describing. This leads me to believe that the problem is actually at some low level that I'm not equipped to understand.

I'm hoping that the collective wisdom on this list might have some ideas. I'm thinking there's something going on with color mapping and Bitmaps (maybe color depths and conversions as well?) which I don't understand very well. On the other hand, I do have a good understanding of the GIF format since I worked on it. The LZW compression is a real nightmare, and even in my Pharo rewrite I had to keep the LZW encoding portions from the original implementation.

The following code, when done in a workspace, will clearly demonstrate the issue:
```
blackForm := Form extent: 100@100.
blackForm getCanvas fillColor: Color black.

"Write to a bytestream"
out := WriteStream on: ByteArray new.
writer := GIFReadWriter on: out.
writer nextPutImage: blackForm.
writer close.

"Read from the bytestream"
in := ReadStream on: out contents.
reader := GIFReadWriter on: in.
result := reader nextImage.

(result colorAt: 50@50) inspect.
```

The resulting color is not what we expect (Color black). It is (Color r: 0.0 g: 0.0 b: 0.004)

Any ideas what's going on?

--
Eric



Reply | Threaded
Open this post in threaded view
|

Re: GIFs and the Color black

darth-cheney


On Sun, Aug 9, 2020 at 3:25 AM karl ramberg <[hidden email]> wrote:
I think Color r: 0.0 g: 0.0 b: 0.0 was/is reserved for transparency in forms with less than 32 bit depth, eg. no alpha channel

Best,
Karl

Hi Karl,

Any idea how to find "where" this is set or happens? If I can track it down, I can compare to Pharo (which doesn't seem to have the issue I'm describing) and see how they deal with it.

For anyone else interested in the problem / example I posted, I can supply a changeset that really breaks out the LZW/GIF compression and decompression stuff so that it's somewhat easier to step through. This is part of the work I did refactoring the current implementation, which is hard to follow.

--
Eric


Reply | Threaded
Open this post in threaded view
|

Re: GIFs and the Color black

timrowledge
In reply to this post by Karl Ramberg


> On 2020-08-09, at 12:24 AM, karl ramberg <[hidden email]> wrote:
>
> I think Color r: 0.0 g: 0.0 b: 0.0 was/is reserved for transparency in forms with less than 32 bit depth, eg. no alpha channel

Yup. It was done that way a loooooooooong time ago for what seemed like good reasons at the time. Digging through the maillist archives probably more than 20 years would find the discussions.

I suppose the question is whether it is really still a good idea, and if not, could we fix it?

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
If you don't pay the exorcist do you get repossessed?






Reply | Threaded
Open this post in threaded view
|

Re: GIFs and the Color black

Karl Ramberg

On Sun, Aug 9, 2020 at 6:47 PM tim Rowledge <[hidden email]> wrote:


> On 2020-08-09, at 12:24 AM, karl ramberg <[hidden email]> wrote:
>
> I think Color r: 0.0 g: 0.0 b: 0.0 was/is reserved for transparency in forms with less than 32 bit depth, eg. no alpha channel

Yup. It was done that way a loooooooooong time ago for what seemed like good reasons at the time. Digging through the maillist archives probably more than 20 years would find the discussions.

I suppose the question is whether it is really still a good idea, and if not, could we fix it?

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
If you don't pay the exorcist do you get repossessed?