Stretching

Hi,

Does anyone here know how sdl stores a bitmap in memory? the reason I ask
is because i want to impletment stretching of bitmaps for my game, and was
just wondering how I could get the sdl_surface and mess around with the
bitmap data so i can stretch it.

thanks. see ya

Ryan Wahle wrote:

Hi,

Does anyone here know how sdl stores a bitmap in memory? the reason I ask
is because i want to impletment stretching of bitmaps for my game, and was
just wondering how I could get the sdl_surface and mess around with the
bitmap data so i can stretch it.

thanks. see ya

The next release of my 16-bit graphix lib will feature stretched blitting.

Paul Lowe
spazz at ulink.net

John Garrison wrote:

Ryan Wahle wrote:

Hi,

Does anyone here know how sdl stores a bitmap in memory? the reason I ask
is because i want to impletment stretching of bitmaps for my game, and was
just wondering how I could get the sdl_surface and mess around with the
bitmap data so i can stretch it.

thanks. see ya

you can scale-blit using somthing like this, untested, just-written code

(For 16bit)

void scale_blit( SDL_Surface *src, SDL_Surface *dst, float xscl, float
yscl ) {
Uint16 *srcptr = (Uint16 *)src->pixels;
Uint16 *dstptr = (Uint16 *)dst->pixels;

int srcX=0, srcY=0;

for( int y=0; y < dst->h; y++ ) {
	for( int x=0; x < dst->w; x++ ) {
		*dstptr = *srcptr;
		dstptr++;
		if( (int)(x / xscl) > srcX ) {
			srcptr+=(int)(x/xscl) - srcX;
			srcX = (int)(x / xscl );
		}
	}
	if( (int)(y / yscl) > srcY ) {
		srcptr+= ((int)(y / yscl) - srcY)*src->w - srcX;
		srcY = (int)(y / yscl);
	}
}

}

Ryan Wahle wrote:

Hi,

Does anyone here know how sdl stores a bitmap in memory? the reason I ask
is because i want to impletment stretching of bitmaps for my game, and was
just wondering how I could get the sdl_surface and mess around with the
bitmap data so i can stretch it.

thanks. see ya

The way my powerpak lib works for rotating (I am still looking for a scaling
routine. I am afraid just multipling the pixels would limit the user to round
number scaling such as doubling the size as I don’t know what would happen if
say every pixel were drawn 1.5 times, only about half would really change
size right?) But anyway the way I do it is to create a temporary surface,
then do a for loop on each pixel and rotate it.(or scale it in your case)
then draw the temporary surface. That way the orignal stays intact. There
might be a faster way than working with each individual pixel, but I don’t
know.

A quite easy way to stretch a bitmap is to use the Hermes library
(http://hermes.terminal.at).
Here is some sample code (without error checking):

//**********************************

HermesHandle handle;
HermesFormat *s, *d;
SDL_Surface *source, *dest;


// load a bitmap into *source or something else
// *dest could be just the screen background

Hermes_Init();
handle = Hermes_ConverterInstance(HERMES_CONVERT_NORMAL);
s = Hermes_FormatNew(source->format->BitsPerPixel,
source->format->Rmask,
source->format->Gmask,
source->format->Bmask,
source->format->Amask, 0);
d = Hermes_Format_New(dest->format->BitsPerPixel,
dest->format->Rmask,
dest->format->Gmask,
dest->format->Bmask,
dest->format->Amask, 0);
Hermes_ConverterRequest(handle, s, d);
Hermes_ConverterCopy(handle,
source->pixels,
sourceX,
sourceY,
sourceWidth,
sourceHeight,
source->pitch,
dest->pixels,
destX,
destY,
destWidth,
destHeight,
dest->pitch);
SDL_UpdateRect(dest, destX, destY, destWidth, destHeight);
Hermes_ConverterReturn(handle);
Hermes_Done();

//***************************

If destWidth and destHeight is the same like sourceWidth and
sourceHeight,
just a normal blitting is done. Otherwise Hermes stretches the "bitmap"
to
the size of the destination. Works fine. I just had some problems with
24 bpp (e.g. loading a BMP-File to source). But a call to
SDL_DisplayFormat(…)
solved the problem.

Hope, I could help you.

Eugen------------------------
Ryan Wahle wrote:

Hi,

Does anyone here know how sdl stores a bitmap in memory? the reason I ask
is because i want to impletment stretching of bitmaps for my game, and was
just wondering how I could get the sdl_surface and mess around with the
bitmap data so i can stretch it.

thanks. see ya

Hello StuartOn 24-Ago-99, you wrote:

John Garrison wrote:

Ryan Wahle wrote:

Hi,

Does anyone here know how sdl stores a bitmap in memory? the reason I
ask
is because i want to impletment stretching of bitmaps for my game, and
was
just wondering how I could get the sdl_surface and mess around with the
bitmap data so i can stretch it.

thanks. see ya

you can scale-blit using somthing like this, untested, just-written code

(For 16bit)

void scale_blit( SDL_Surface *src, SDL_Surface *dst, float xscl, float
yscl ) {
Uint16 *srcptr = (Uint16 *)src->pixels;
Uint16 *dstptr = (Uint16 *)dst->pixels;

int srcX=0, srcY=0;

for( int y=0; y < dst->h; y++ ) {
    for( int x=0; x < dst->w; x++ ) {
        *dstptr = *srcptr;
        dstptr++;
        if( (int)(x / xscl) > srcX ) {
            srcptr+=(int)(x/xscl) - srcX;
            srcX = (int)(x / xscl );
        }
    }
    if( (int)(y / yscl) > srcY ) {
        srcptr+= ((int)(y / yscl) - srcY)*src->w - srcX;
        srcY = (int)(y / yscl);
    }
}

}

Umh…make floating point calcs in a blit routine
is not suitable for a slow processor.
I think that some fixed point calculation should be much faster.

#define fxp 16

void scale_blit (SDL_Surface *src, SDL_Surface *dst)
{

UInt16 *srcptr = (UInt16 *)src->pixels;
UInt16 *dstptr = (UInt16 *)dst->pixels;
UInt16 *ptry,*ptrx;

int dx = (((int)(src->w))<<fxp)/(int)dst->w;
int dy = (((int)(src->h))<<fxp)/(int)dst->h;

int x=0;
int y=0;


for ( int j=0; j < dst->h ; j++);
{

    ptry = (y>>fxp)*src->w*sizeof(UInt16) + srcptr;
    y = y+dy;
    
    for ( int i=0; i < dst->w; i++);
    {
        ptrx = ptry + x>>fxp;    
        *dstptr = *ptrx;
        dstptr++;
        x = x+dx:
    }
}

}

I have not tested it but should works :slight_smile:
One can increase precision modifying fxp, anyway 16 bits
shoould be enough.
It’s obvius that works only with 16 bit video modes.

Hi,

Does anyone here know how sdl stores a bitmap in memory? the reason I ask
is because i want to impletment stretching of bitmaps for my game, and was
just wondering how I could get the sdl_surface and mess around with the
bitmap data so i can stretch it.

It depends on the format of the SDL_Surface containing your bitmap.
You’ll have to look at the SDL_PixelFormat structure associated with it.
If it’s an 8-bit indexed color image, the pixels member of SDL_Surface
can just be cast to (char *) and accessed like an array. This code
fragment accesses the pixel at x, y:

SDL_Surface *s;
Uint32 offset, x, y, pixel;

offset = y*s->pitch + x;
pixel = ((Uint8 *)s->pixels)[offset]];

Now, if the pixelformat is not 8bpp, you will have to get a number of
bytes equal to s->format->BytesPerPixel. For example, you could do the
following:

Uint32 pixel;
Uint8 r, g, b;

offset = ys->pitch + xs->format->BytesPerPixel;
memcpy(&pixel, s->pixels + offset, s->format->BytesPerPixel);
pixel &= (1<format->BitsPerPixel)-1;
SDL_GetRGB(pixel, s->format, &r, &g, &b);

to get the RGB components. This should work for any surface whose bits
per pixel is divisible by 8. (is this safe to do on big-endian
architectures? I know this works on Linux/Intel!) If it’s one of those
odd-bit surfaces, well, that’s a little more complicated!

I’ve thought of a high quality, but obviously expensive algorithm for
stretching an m x n array of pixels into an (m+p) x (n+q) array. First
use a 2D-FFT algorithm to produce an m x n array of frequency
coefficients. Expand this array to an (m+p) x (n+q) array, filling the
extra coefficients with zeroes. Inverse Fourier to get back to the space
domain and the expanded image. I think that this would produce better
results than the bilinear/spline interpolation techniques used by most
bitmap scaling programs, because the effective filter’s support is over
the entire image, not just in a 2- or 3-pixel radius. This is, of course,
overkill for what is being done…On Tue, 24 Aug 1999, Ryan Wahle wrote:


| Rafael R. Sevilla @Rafael_R_Sevilla_94 |
| Instrumentation, Robotics, and Control Laboratory |

College of Engineering, University of the Philippines, Diliman