PDA

View Full Version : How do you use IMG_Load_RW...



M109uk
27-03-2007, 10:47 PM
Hi all,

I have data stored in a memory stream, i am trying to use SDL_Image to load the image.

I currently have the following code:



var
SDLStream: TSDL_RWops;

SDLStream := StreamToRWops(_XPacks.Items[Index].GetStream(Filen ame).Stream);
Surface := IMG_Load_RW(@SDLStream, 1);
If Surface = Nil Then Exit;




function Seek(Context: PSDL_RWops; Offset: Integer; Whence: Integer): Integer;
var
Stream: TStream;
begin
Stream := TStream(Context^.unknown.data1);
If Stream = Nil Then
Begin
Result := -1;
Exit;
End;

Case Whence Of
SEEK_SET: Stream.Position := Offset;
SEEK_CUR: Stream.Position := Stream.Position+Offset;
SEEK_END: Stream.Position := Stream.Size+Offset;
End;
Result := Stream.Position;
end;

function Read(Context: PSDL_RWops; Ptr: Pointer; Size: Integer; Maxnum: Integer ): Integer;
var
Stream: TStream;
begin
Stream := TStream(Context^.unknown.data1);
If Stream = Nil Then
Begin
Result := -1;
Exit;
End;
Result := Stream.Read(Ptr^, Size*Maxnum) Div Size;
end;

function Write(Context: PSDL_RWops; Ptr: Pointer; Size: Integer; Num: Integer ): Integer;
var
Stream: TStream;
begin
Stream := TStream(Context^.unknown.data1);
If Stream = Nil Then
Begin
Result := -1;
Exit;
End;
Result := Stream.Write(Ptr^, Size*Num) Div Size;
end;

function Close(Context: PSDL_RWops): Integer;
var
Stream: TStream;
begin
Stream := TStream(Context^.unknown.data1);
if Stream = nil then
begin
Result := -1;
Exit;
end;
Stream.Destroy;
context^.unknown.data1 := nil;
Result := 0;
end;

function StreamToRWops(Stream: TStream): TSDL_RWops;
begin
Result.type_ := 2;
Result.unknown.data1 := Stream;
Result.seek := @Seek;
Result.read := @Read;
Result.write := @Write;
Result.close := @Close;
end;

procedure RWopsToStream(RW: PSDL_RWops; Stream: TStream);
var
Buf: Pointer;
Read: Integer;
begin
If Stream = Nil Then Exit;
If RW = Nil Then Exit;
GetMem(Buf, 1024);
Try
Read := RW^.Read(RW, Buf, 1, 1024);
While Read > 0 Do
Begin
Stream.Write(Buf^, Read);
Read := RW^.Read(RW, Buf, 1, 1024);
End;
Finally
FreeMem(Buf);
End;
end;


Everytime i get to the stage of loading the data to IMG_Load_RW i get an access violation.

Does anyone know if im i missing something?

Many Thanks

paul_nicholls
28-03-2007, 12:35 AM
If it helps you, this is my code I use for this sort of thing:


Procedure TSpriteSource.LoadFromMem(mem: Pointer; size: Integer);
Var
Surface : PSDL_Surface;
rw : PSDL_RWops;
Begin
If &#40;mem = Nil&#41; Or &#40;size <= 0&#41; Then Exit;
rw &#58;= SDL_RWFromMem&#40;mem,size&#41;;
If rw = Nil Then Exit;
Surface &#58;= SDL_LoadBMP_RW&#40;rw,0&#41;;
SDL_FreeRW&#40;rw&#41;;
If Surface = Nil Then Exit;
If FSurface <> Nil Then SDL_FreeSurface&#40;FSurface&#41;;
FSurface &#58;= Surface;
<SNIP>
End;

Of source as you are using SDL_Image, you would replace the SDL_LoadBMP_RW with IMG_Load_RW.
In your case I am not sure if you should be freeing the memory with the 1 parameter though.

cheers,
Paul.

M109uk
28-03-2007, 03:15 PM
Thanks paul_nicholls,

Your code was a great help, just had to load the stream data into a pointer and it all seems to work great :)

M109uk
28-03-2007, 03:53 PM
Is there a problem with loading TGAs this way?

All my textures work except for any that are in the tga format.

Thanks

Edit:
Nevermind, it works ok if i use IMG_LoadTGA_RW..

technomage
28-03-2007, 07:24 PM
JEDI-SDL v1.0 (from cvs) ships with an sdlstreams.pas unit. Which takes care of doing all the stream stuff for you.

I use this succesfully with not only Img_Load_RW but also TTF_Load_RW for loading fonts. It works really well.

paul_nicholls
28-03-2007, 11:26 PM
Thanks paul_nicholls,

Your code was a great help, just had to load the stream data into a pointer and it all seems to work great :)

Glad to help! :)
Just giving something back to the forum :-)
cheers,
Paul.