Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDL_RWread returns 0 for valid offset and length #481

Closed
SDLBugzilla opened this issue Feb 10, 2021 · 0 comments
Closed

SDL_RWread returns 0 for valid offset and length #481

SDLBugzilla opened this issue Feb 10, 2021 · 0 comments

Comments

@SDLBugzilla
Copy link
Collaborator

This bug report was migrated from our old Bugzilla tracker.

These attachments are available in the static archive:

Reported in version: HG 2.0
Reported for operating system, platform: Android (All), All

Comments on the original bug report:

On 2011-09-05 16:39:47 +0000, wrote:

I experienced this error attempting SDL_ttf's TTF_OpenFont on android.

My FreeSans.ttf is 264072 bytes. At some point tt_face_load_font_dir() calls SDL_ttf's RWread() with offset 224160 and length of 4. The call to SDL_RWseek() successfully returns 224160. However the subsequent call to SDL_RWread() for 4 bytes returns 0.

On 2011-09-05 16:46:03 +0000, wrote:

SDL_rwread() returns 0 because mEnv->CallIntMethod(readableByteChannel, readMethod, byteBuffer) returns -1.

On 2011-09-06 02:47:51 +0000, Tim Angus wrote:

Could you perhaps put together a minimal test case for reproducing this bug and I'll take a look? I've been using freetype directly with this code and it apparently works fine so it's a bit odd that SDL_ttf would fail. Indeed I tried loading a copy of FreeSans.ttf (of the same size) using freetype and it worked.

I suspect the problem will be related to seeking, most likely because Java and SDL's idea of file position is getting out of sync somehow. That's my best guess at the moment anyway.

On 2011-09-06 11:31:32 +0000, wrote:

Well, unfortunately this test case is well described. It's just TTF_Open_Font() FreeSans.ttf on android.

How are you using freetype directly on android? I assume you would supply a read callback to FT_Open_Face() via TTF_Font->arg.stream->read, that would perform a SDL_RWseek() and SDL_RWread(), exactly analogous to SDL_ttf's RWread().

If you add logging to your read callback I expect that you would see a seek to offset 224160 and a read of 4 bytes returning 4, where as I see it return 0. I'm running on version 1.6 of android emulator.

I agree that the problem is likely related to seeks. I am reading .png's OK on android via SDL. Tonight I will attempt a work around by first reading the .ttf into a buffer, then initializing freetype with a SDL_RWops returned by SDL_RWFromMem().

On 2011-09-07 05:39:09 +0000, Tim Angus wrote:

Created attachment 700
Logging of TTF_OpenFont( "FreeSans.ttf", 24 )

Is this the part where you see the read return 0?

I/SDL (23133): Android_JNI_FileSeek( 0x2ba910, 224160, 0 )
I/SDL (23133): returning 224160
I/SDL (23133): Android_JNI_FileSeek( 0x2ba910, 224160, 0 )
I/SDL (23133): returning 224160
I/SDL (23133): Android_JNI_FileRead( 0x2ba910, 0x44bb619c, 1, 4 )
I/SDL (23133): returning 4

Clearly I don't see this so there is little I can do to help unless you provide a reproducible test case. It might be worth trying a different android API level. We might unwittingly be relying on some newer/changed functionality.

On 2011-09-08 21:36:56 +0000, wrote:

Yep, that's the one! (The SDL_RWread() that returns 0 for me.) I'm running android simulator 1.6 on i386 OSX.

The work-around I described works nicely. (And probably is more efficient.)

Do you mean try running on some higher version like AVD 1.7? The SDL docs say to use 1.6.

On 2011-09-09 02:34:03 +0000, Tim Angus wrote:

(In reply to comment # 5)

Yep, that's the one! (The SDL_RWread() that returns 0 for me.) I'm running
android simulator 1.6 on i386 OSX.

Could you provide a code dump so I can check this out? It sounds pretty incidious and well hidden so it deserves being examined closely while the chance is there. Better that than random failures in the future.

The work-around I described works nicely. (And probably is more efficient.)

Most likely, yes.

Do you mean try running on some higher version like AVD 1.7? The SDL docs say
to use 1.6.

Yep. The API level is just a guideline; SDL should work with anything since 1.6. I'm currently targeting android-10 (2.3) for simplicity but will likely later drop this down a bit.

On 2011-09-09 17:16:53 +0000, wrote:

I have tested this on a second i386/OSX android simulator 1.6 and received the same results. I expect that you will reproduce this bug if you run your code on 1.6.

I will try on 2.3 tonight.

On 2011-09-09 18:54:28 +0000, wrote:

Turns out same thing happens to me on 2.3.3. I have to update my expectation to I don't know.

What OS are you using?

Maybe its just unique to my code and build procedure.

On 2011-09-12 02:12:56 +0000, Tim Angus wrote:

I'm using Windows 7, testing on a Samsung Galaxy. I can't use the emulator since it doesn't support OpenGL ES 2. I think I really need to see your code to be able to debug the problem...

On 2011-10-14 07:54:17 +0000, Gabriel Jacobo wrote:

Created attachment 712
Fixes seeking in Android

I've figured out where the problem is. If you trace what freetype does, there's a point where the read pointer is at offset 156. Then comes a SEEK_SET to position 280 where the magic code is.
Android_JNI_FileSeek is called and it correctly identifies that it needs to skip 124 bytes forward, but when it attemps to:

movement -= mEnv->CallLongMethod(inputStream, skipMethod, movement);

If you catch the return value of this call you'll see that it's not 124 as expected, nor it is less...it's MORE, actually it returns the file size - 156, which is very very odd (http://developer.android.com/reference/java/io/InputStream.html#skip%28long%29 indicates that it will NOT skip more bytes than requested). It certainly looks like a bug on the Android, what still bothers me is that it doesn't happen with every seek position, only this particular one (at least that I've noticed) seems to trigger this behaviour.
The attached patch replaces the call to skip by one or more calls to Android_JNI_FileRead, which should not be much more inefficient as the skip method documentation claims that what it does is read the bytes into a temporary buffer anyway.

This solves the problem for me, let me know if it works for you as well.

On 2011-10-14 09:36:28 +0000, Tim Angus wrote:

Created attachment 713
Work around apparently buggy Android Inputstream::skip implementation

Ah, well spotted. My experience with Android so far has not been entirely positive, I have to say; so I'm not really surprised that skip is misbehaving. I've made a couple of changes to your patch:

  • Use a buffer on the stack instead of malloc'ing
  • When the read fails give up on the seek entirely (like the other platforms)
  • Remove any references to the skip method since we're not using it any more

Thanks for working this one out!

On 2011-10-14 11:50:09 +0000, Ryan C. Gordon wrote:

Tim's patch is now hg changeset c9cb52d6d864, thanks!

--ryan.

On 2011-10-25 11:40:42 +0000, Gabriel Jacobo wrote:

*** Bug 1318 has been marked as a duplicate of this bug. ***

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant