Scaling images

ok, i’m finding there’s no SDL support for scaling surfaces.
i’m needing this, and i figure if i’m gonna do it, i might as
well do it right and make it work for all SDL.

so at this point i’m looking for requests/proposals/ideas.
here is my current spec. unless i hear better ideas these
are the changes i will make…

first, i’ll simply be adding a function

SDL_Surface* SDL_ResizeSurface(SDL_Surface* surf,
int width, int height,
int filter)

pretty basic, i would include a set of standard filters
(closest, linear, cubic, and maybe some others…)
it takes a surface and a new width and height, it
returns a new surface of the same style and fills
it with the resampled image

another goal would be to take the SDL_BlitSurface() and
allow the user to use different sized rectangles
(i suspect this was a goal all along?) anyways, i’ll
likely hold off on this change for awhile, because there
are “deeper” issues. mainly what “filter” should be used
when blitting.

the only other things i wonder about are…

  • like i mentioned, if you do a scale while blitting
    what style of filtering to use? i’m not too keen on
    making it a global “state machine” type setting, but
    the only other option is to add arguments to blitting.
  • i’m pretty sure directdraw supports hardware scaling
    how is this best handled? adding a “hardware” filter
    type would be my best guess
  • i’ve seen that there is support for scaled video
    surfaces. i’ve never looked into this yet (i will be)
    but are there some good standards i should follow?

anyways, i’m totally open to suggestions, and it
shouldn’t take me long to get this up and running.
i just want to be sure its handled in a way that
helps the most people out

(glad to see you back, sam)

ok, i’m finding there’s no SDL support for scaling surfaces.

Try SDL_SoftStretch()

i’m needing this, and i figure if i’m gonna do it, i might as
well do it right and make it work for all SDL.

pretty basic, i would include a set of standard filters
(closest, linear, cubic, and maybe some others…)

SDL_SoftStretch only seems to use nearest-neighbour interpolation, and
I agree that it should be a parameter. I don’t know what other methods
of interpolation (besides that, bilinear, and bicubic) you had in mind.

  • i’m pretty sure directdraw supports hardware scaling
    how is this best handled? adding a “hardware” filter
    type would be my best guess

Can’t sdl decide to use hardware acceleration directly if it is faster?

ok, i’m finding there’s no SDL support for scaling surfaces.

Try SDL_SoftStretch()

Shh! Don’t tell! :slight_smile:

This function isn’t exported because of the wide variety of issues
surrounding stretching, such as hardware acceleration, filtering,
and format conversion. If some people are interested in investigating
all these issues to “do it right”, I’ll be happy to lend whatever
assistance I can.

See ya!
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

Well, well,…

Once again.

FOR ALL PEOPLE WHO WANT TO STRETCH IMAGES
AND DO FORMAT CONVERSION PLEASE CHECKOUT
MY STRETCHLIB …

ftp://ftp.bms-austria.com/pub/linux/SDL/stretchdemo-0.2.tar.gz

PS: i am quite tired about that!

PPS: To Sam: I’ll make a lib of that… could you please point (link) to
it
Thank’s in advance

Sam Lantinga wrote:> > >ok, i’m finding there’s no SDL support for scaling surfaces.

Try SDL_SoftStretch()

Shh! Don’t tell! :slight_smile:

This function isn’t exported because of the wide variety of issues
surrounding stretching, such as hardware acceleration, filtering,
and format conversion. If some people are interested in investigating
all these issues to “do it right”, I’ll be happy to lend whatever
assistance I can.

See ya!
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

Mattias wrote:

SDL_SoftStretch only seems to use nearest-neighbour interpolation, and
I agree that it should be a parameter. I don’t know what other methods
of interpolation (besides that, bilinear, and bicubic) you had in mind.

i’ve found algorithms for some different filters. mainly i assume
they try to make tradoffs in quality for speed. i haven’t tried
any of them yet, so i was planning on seeing what they offered.

Alexander wrote:

FOR ALL PEOPLE WHO WANT TO STRETCH IMAGES
AND DO FORMAT CONVERSION PLEASE CHECKOUT
MY STRETCHLIB …

ftp://ftp.bms-austria.com/pub/linux/SDL/stretchdemo-0.2.tar.gz

PS: i am quite tired about that!

heh, sorry to hit a sore spot. your stretching looks good, and
maybe someone (not me, i’m too afraid to go that “lowlevel”)
can implement that stretching as the default stretching for
the software video driver?

Sam Lantinga wrote:

This function isn’t exported because of the wide variety of issues
surrounding stretching, such as hardware acceleration, filtering,
and format conversion. If some people are interested in investigating
all these issues to “do it right”, I’ll be happy to lend whatever
assistance I can.

it seems there would be a need for another function pointer in
the graphics driver structure that would handle the hardware
scaling of images. what’s scary is that different windows gfx
cards do different scaling. most are “nearest neighbor”, but
the newer cards seem to do filtered scaling. i think i remember
some API commands to check what type of scaling the card will
do. under windows GDI there is a scaled blit operation, and
directx offers scaling as part of it’s standard blitting tools.
i’m not sure what X & Mac have to offer, but there should be a
good middleground for all platforms?
being able to scale an individual surface and scale an image
during blit would both be handy!
i’m afraid i wouldn’t be a lot of help getting this going.
i’m quite new to the SDL library, and this is all lower level
stuff. it would behoove everyone to get this right the first
time :]

i believe i’ll still write my “filtered” scaling. if people
are interested i’ll release it as a library, or try to get
it adopted into standard SDL

i’ve found algorithms for some different filters. mainly i assume
they try to make tradoffs in quality for speed. i haven’t tried
any of them yet, so i was planning on seeing what they offered.

I’d say all three common modes of interpolation (nearest-neighbour,
bilinear and bicubic) are useful, but there should be a way to query the
performance (which modes are hardware-accelerated etc).

This sort of code lends itself very well to hand-hacked SIMD asm (as a hint
to all altivec/3dnow/mmx/vis/sse/etc hackers out there). Once there is a
reasonable infrastructure in place, people can start coding.
One part of that infrastructure that should not be forgotten is a good
test/benchmark program, both for verification and tuning.

Mattias Engdeg?rd wrote:

This sort of code lends itself very well to hand-hacked SIMD asm (as a hint
to all altivec/3dnow/mmx/vis/sse/etc hackers out there). Once there is a
reasonable infrastructure in place, people can start coding.
One part of that infrastructure that should not be forgotten is a good
test/benchmark program, both for verification and tuning.

hmm, good thinking. well now i’m a little worried. the resampling
i was going to do was based strongly on some graphics gems code.
i’m not sure how easily this could be transferred to SIMD. i know
some algorithms are extremely difficult to take advantage of SIMD.
but that’s about as much as i know :]

owell, at this point i think i should hold off, and let the
"gurus" lay down the infrastructure for this type of stuff.
then maybe be able to help out after that

I’m certainly interested in this feature, but it has to be fast enough
for full-window blits at gameplay frame-rate. In Exult, I’ve
implemented a 2X scaler in C++ that does bilinear filtering. Looks
really good. But its speed at doubling a 320x200 pixel window is barely
acceptable on a K6/333, although that’s with optimization turned off.
You might consider having a 2X scaler as a special case, since the code
is MUCH simpler than for general scaling.

Of course, we all really want hardware acceleration. But what’s
available that will work on all platforms? Has anyone tried the SMPEG
trick of using OpenGL with the frame buffer fed to the engine as
textures?