SDL_image and JPEG->8bit : patch

Hi !

Since my game is running in 256 color mode, I needed a way to display a
JPEG image there with an optimized palette. SDL doesn’t offer a
function to reduce a 24 bit surface to a 8 bit surface generating an
optimized palette, or did I fail to notice it?

Since the Jpeg library has a nice color quantization function, I
enhanced SDL_image to use it. I’ve attached the patches.

First I tried to give IMG_LoadJPG_RW a second parameter depth with
default value of 24 (defined in the header file). But GCC didn’t want
that. Then I tried to overload IMG_LoadJPG_RW with a second function
having two arguments. Didn’t work either. Then I’ve made a completely
new function: IMG_LoadJPG_RW_D , which worked.
I hate C …

Bye,
Martin

-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/octet-stream
Size: 3526 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20000805/69484de7/attachment.obj
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/octet-stream
Size: 586 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20000805/69484de7/attachment-0001.obj

Since my game is running in 256 color mode, I needed a way to display a
JPEG image there with an optimized palette. SDL doesn’t offer a
function to reduce a 24 bit surface to a 8 bit surface generating an
optimized palette, or did I fail to notice it?

Nah, it’s not really within SDL’s domain, it can be done in a platform-
independent way by the programmer. There are a lot of interesting ways
to do that though. I think SDL creates an awful 332 palette.

I’ve taken a look at libjpeg and it can apparently use two palettes:
The default is to use a two-pass algorithm and compute some kind of
best-possible map and use that, but you can also have it use a
standard 6x7x6 colour brick which is slightly faster. Then it uses
a fairly standard Floyd-Steinberg dither to calculate the indices.

But I don’t really understand your motivation. Unless you are going
to show only one picture at a time, don’t you want to use a common
palette for all image work? Your patch generates a different palette
for each loaded picture. Perhaps you are better off with a different
(8-bit) image format.

Since the Jpeg library has a nice color quantization function, I
enhanced SDL_image to use it. I’ve attached the patches.

This can be useful, but I’m not quite sure how to handle this in a
format-independent way.

First I tried to give IMG_LoadJPG_RW a second parameter depth with
default value of 24 (defined in the header file). But GCC didn’t want
that. Then I tried to overload IMG_LoadJPG_RW with a second function
having two arguments. Didn’t work either. Then I’ve made a completely
new function: IMG_LoadJPG_RW_D , which worked.
I hate C …

Begone, you lowly C++ spawn of hell! Back to your tar pit! :wink:

Since my game is running in 256 color mode, I needed a way to display a
JPEG image there with an optimized palette.

But I don’t really understand your motivation. Unless you are going
to show only one picture at a time, don’t you want to use a common
palette for all image work? Your patch generates a different palette
for each loaded picture.

That is exactly what I want: Displaying a single large (fullscreen)
picture, without anything else on the screen. For example the title
screen.
For normal, small ingame graphics I wouldn’t use JPEG anyway.

Bye,
MartinOn Mon, 7 Aug 2000 00:56:35 +0200 (MET DST), Mattias Engdeg?rd wrote:

That is exactly what I want: Displaying a single large (fullscreen)
picture, without anything else on the screen. For example the title
screen.
For normal, small ingame graphics I wouldn’t use JPEG anyway.

OK, that’s a valid use. You could get the same effect by loading the
jpeg into a 24bit RGB surface and dither yourself, but it would be silly
not to use the quantisation and FS code in libjpeg now that it’s there.

The problem is rather how to implement this in a good way in SDL_image.
Some ideas are:

  • IMG_LoadWithColormap(source, colormap) that allows you to give it
    a colourmap to dither to, or pass NULL to let it choose its own
  • IMG_LoadDitheredTo(source, depth) that dithers down to a certain
    depth (probably 8 or 16bpp)
  • just give up and make special calls for each format IMG_Jpeg_Load(…)

A 24->15 or 16 bit ditherer would actually be handy sometimes (unless you
belong to the group of people who think that if you notice the difference
between 24 and 16 bit, your game is too slow-paced anyway)