square / picasso

A powerful image downloading and caching library for Android
https://square.github.io/picasso/
Apache License 2.0
18.71k stars 3.97k forks source link

Exception: java.io.IOException: Cannot reset #364

Closed madmed closed 8 years ago

madmed commented 10 years ago

Hi Square team!

We are having an issue in an app, when in a listview, images on some rows load but some of them are blank. I tried to trace it and collect as much information as I can.

Exception

Picasso:Error:ImageLoadFailed:Uri http://store.indemand.com/shared/ovs/prodimages/movies/t/troublewiththecurve_ID0360906/troublewiththecurveBM_ID0360906.jpg

Picasso:Error:ImageLoadFailed:Exception java.io.IOException: Cannot reset

Picasso:Error:ImageLoadFailed:StackTrace 
[
    com.squareup.picasso.MarkableInputStream.reset(MarkableInputStream.java:94), 
    com.squareup.picasso.NetworkBitmapHunter.decodeStream(NetworkBitmapHunter.java:91), 
    com.squareup.picasso.NetworkBitmapHunter.decode(NetworkBitmapHunter.java:60), 
    com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:111), 
    com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:82), 
    java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:390),
    java.util.concurrent.FutureTask.run(FutureTask.java:234), 
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080), 
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573), 
    java.lang.Thread.run(Thread.java:856), 
    com.squareup.picasso.Utils$PicassoThread.run(Utils.java:218)
]

Responsible code (under getView())

pBuilder.build().load(URL).fit().into(ImageView);

By the way, I don't know if it matters but airplane mode is on, but wifi is connected. I added this because with every row loading, I am seeing this in logs:

W/Settings(4289): Setting airplane_mode_on has moved from android.provider.Settings.System to android.provider.Settings.Global, returning read-only value.

Also the app crashed with this, after scrolling through the list up and down many times;

A/Looper(4289): Could not create wake pipe.  errno=24
A/libc(4289): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 5091 (Picasso-Dispatc)
A/libc(4289): Unable to open connection to debuggerd: Too many open files

The app doesn't seem to crash and I also didn't see the W/Settings airplane message if I switch to

Picasso.with(_context).load(URL).fit().into(imageView);

style instead of Picasso.Builder.

dnkoutso commented 10 years ago

This has been an issue with various images and the quick bad solution was to increase the MARKER size in NetworkBitmapHunter.

Do you have some sample urls of images failing? Try to bump it to 131072 and see if that works.

dnkoutso commented 10 years ago

As for the airplane mode that seems to be OK as a warning since the API has changed. I'll verify again today.

We will be upgrading Picasso to use Gradle and API Level 19 and when we do so we will fix that warning.

madmed commented 10 years ago

The image is a small one: http://store.indemand.com/shared/ovs/prodimages/movies/t/troublewiththecurve_ID0360906/troublewiththecurveBM_ID0360906.jpg , around 120KB.

I couldn't see a method call to adjust the MARKER size, should I change that in source and compile my own jar?

dnkoutso commented 10 years ago

For now yes, I believe there is an issue filed to properly fix this.

madmed commented 10 years ago

I had to increase the MARKER size to 1048576 to get all sample images to show and they were small thumbnails.

JakeWharton commented 10 years ago

That seems like a wicked Android bug either in skia or one of the decoding libraries that it uses. We should file a bug. What version of Android?

madmed commented 10 years ago

Our minSDK=14 and max/targetSDK=19.

It looks like either Picasso or Android is having trouble as images get smaller. We have an even smaller thumbnail right next to the notification text when something is downloading and we weren't able to get that image to show.

niekvse commented 10 years ago

We're having the same issue, on all the Android phones I tested it on (4.4 and 4.3), and it only shows up when using Picasso. If I just use the BitmapFactory to create the same Bitmap (from the same source), it works fine. So, it's an issue specific to Picasso. @JakeWharton: could you elaborate on the "wicked Android bug" that you say is causing this, so we have a way to work around this? Increasing the MARKER size didn't make a difference in our case. Thanks!

JakeWharton commented 10 years ago

The metadata for every image format is present in the first 1024 bytes of the image. The images on which Android decides to read a ton of data on a metadata-only decode contain the relevant data in the first 1024 bytes. Something is causing the native decoding libraries to read much more data than they need to fulfill the metadata decode we are requesting.

niekvse commented 10 years ago

Thanks @JakeWharton! I understand the issue now. But, as far as I can see in the docs, you don't have any guarantee from the Android API's (inJustDecodeBounds) about how many bytes will be read in order to determine the image bounds. So, I don't really see how Picasso can rely on an arbitrary value (2^16; 65536) and expect it to work in all cases. It may well be an inefficient implementation on Android's part, but it seems wrong to blame them for something they don't guarantee? Additionally, even if it were a bug on Android and they fixed it, it doesn't really help Picasso users ;) (until everybody upgrades..)

JakeWharton commented 10 years ago

I'm looking at the implementation of bounds decoding, not the docs. It also assumes that they are in the first 1024 bytes.

niekvse commented 10 years ago

Thanks @JakeWharton! But how can Picasso rely on Android's implementation details? Or am I missing something? When you use their inJustDecodeBounds API to figure out the dimensions of the image, you should not rely on implementation details, but on the published java docs; i.e., the actual contract. They may change this implementation. As long as the API's don't specifically mention implementing this bounds decoding a certain way, any code using this API shouldn't rely on the implementation. So, clearly, it seems a bug in Picasso, not in Android. By following the published API, these problematic images can be loaded without problems. Can we expect this issue to be fixed in Picasso in some future release, or should we work around it ourselves somehow? Thanks again!

JakeWharton commented 10 years ago

It will be fixed.

On Fri, Apr 25, 2014 at 12:03 PM, niekvse notifications@github.com wrote:

Thanks @JakeWharton https://github.com/JakeWharton! But how can Picasso rely on Android's implementation details? Or am I missing something? When you use their inJustDecodeBounds API to figure out the dimensions of the image, you should not rely on implementation details, but on the published java docs; i.e., the actual contract. They may change this implementation. As long as the API's don't specifically mention implementing this bounds decoding a certain way, any code using this API shouldn't rely on the implementation. So, clearly, it seems a bug in Picasso, not in Android. By following the published API, these problematic images can be loaded without problems. Can we expect this issue to be fixed in Picasso in some future release, or should we work around it ourselves somehow? Thanks again!

— Reply to this email directly or view it on GitHubhttps://github.com/square/picasso/issues/364#issuecomment-41428247 .

lidemin commented 10 years ago

Hi, @JakeWharton . Correct me if i was wrong.

https://github.com/square/picasso/pull/487

I am not so sure about the original purpose of those 2 lines of codes . Seems like after I removed them this issue was gone.

Thanks.

yincrash commented 10 years ago

My Moto G is making photos that run in to this bug on decoding. Is there a good way to fix existing bitmaps until a fix is in place?

dnkoutso commented 9 years ago

Known issue and number 1 priority for 2.5.1. No more MarkableInputStream problems.

jacobtabak commented 9 years ago

@dnkoutso Is there a workaround for this I could use on a fork? Also I'm trying to get some more context on the issue - you kind of commented out of the blue that it's a known issue. Is there more discussion elsewhere?

We're experiencing this problem specifically on Moto X (2nd gen) loading a full-resolution capture from the camera, using resize() to cap it at 1200x1200 px.

dnkoutso commented 9 years ago

@jacobtabak have you tried increasing the MARKER constant in NetworkRequestHandler? I think the constant was removed but the problem is sometimes Picasso is trying to find the dimensions of the bitmap so it doesnt decode all of it.

If you increase it it will work. We will be working on this to fix it once and for all.

jacobtabak commented 9 years ago

Thanks @dnkoutso,

We're loading from disk in this case, so unless that MARKER constant is also used in the FileRequestHandler, I'm not sure that will help.

We have narrowed it down to something that changed between 2.4 and 2.5.

By just reverting Picasso 2.4 (and by extension re-adding the okhttp-urlconnection dependency) the issue was resolved.

Unfortunately it's only happening on one device that I don't own (Moto X 2nd gen) so I can't really narrow down the exact change that broke it.

sbakhtiarov commented 9 years ago

Just fixed a similar issue in my app. Same conditions: Lollipop, ListView and Picasso for loading images in the list items. On list scroll I occasionally got SEGSEGV. And it worked on the ICS device without any issues.

Problem was in this code for setting up list item:

if (some_condition) {
    picasso.load(url).into(imageView);
} else {
    imageView.setImageResource(placeholderResId);
}

Solved with using picasso in both cases.

tambeti commented 9 years ago

As a work around, I wrote a small patch to allow to provide original image dimensions, so if you do have these, the problematic code path could be avoided.

https://github.com/litl/picasso/pull/1/files

keekerdc commented 9 years ago

Also experiencing this on latest Picasso version just on Moto X 2 (API 21). Reverting to 2.4 as @jacobtabak mentioned above resolved the issue (thanks)!

mikeiansky commented 9 years ago

I have a problem , how to increase the MARKER size ?I had a big network bitmap for size (4608x3072) can not load !

nemanja-kovacevic commented 9 years ago

Same here, 2.5.2, Moto X 2nd gen, all is well on other devices I have...

bagintz commented 9 years ago

I am also having this issue in 2.5.2, Moto G 1st gen

mroczis commented 9 years ago

Hey, I'm not sure if I may help you but I'm also facing this problem. This exception is sometimes present no matter how image resolution is big. Lately I was trying to load a 360x360 file from the internet without any success. One of the images I can't load is located here - http://dotekomanie.cz/wp-content/uploads/2015/04/HTC-One-M8s_PerLeft_GunMetal-360x360.jpg

W/System.err﹕ java.io.IOException: Cannot reset
W/System.err﹕ at com.squareup.picasso.MarkableInputStream.reset(MarkableInputStream.java:99)
W/System.err﹕ at com.squareup.picasso.BitmapHunter.decodeStream(BitmapHunter.java:140)
W/System.err﹕ at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:217)
W/System.err﹕ at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:159)
W/System.err﹕ at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
W/System.err﹕ at java.lang.Thread.run(Thread.java:818)
W/System.err﹕ at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:411)

Nexus 5, Android M + Android 5.1.1, Picasso 2.5.2

dnkoutso commented 9 years ago

Known issue and tracked for next version. One day. Apologies for this delay.

skhaz commented 9 years ago

Same issue on Moto E with Android 4.4.4 while loading image from disk.

BaronZ commented 9 years ago

v 2.5.2 still have this issue while loading local image @dnkoutso @JakeWharton if i dont use resize, i got OOM

BaronZ commented 9 years ago

works fine using v 2.4.0

chrjsorg commented 9 years ago

Can confirm. Works fine with v2.4.0. 2.5.2 gave me the same error

picassoInstance.load(uri).fit().into(imageView);
uri = file:///storage/emulated/0/WhatsApp/Media/WhatsApp%20Images/IMG-20150724-WA0009.jpeg
jeronimo75 commented 9 years ago

Alas, the last fix is not fixing anything. I have got in the BitMapHunter.java: long mark = markStream.savePosition(65536); // TODO fix this crap. However I have a call line 140: markStream.reset(mark); and within the markStream the offset=66562 Therefore the reset is failing with the infamous IOException "cannot reset".

I attach the faulting image in case it helps your debugging. I have lollipop.

63_2hodchmmj_43927

illarionov commented 9 years ago

The default MARKER size of 65536 bytes is not enough for a JPEG file having an 65534 bytes EXIF header.

The value of 65536+2048 works better in this case.

capezzbr commented 9 years ago

Any update on this issue?

eygraber commented 9 years ago

+1 I'm seeing this when loading images taken by a Droid Turbo 5.1 using 2.5.2

Jaymassena commented 9 years ago

I'm trying to guage whether I should fork and try some of the work-arounds floating on different issue threads or sit tight till 2.5.3. Any broad guidance on when 2.5.3 might be released?

eygraber commented 9 years ago

They don't do ETAs

Jaymassena commented 9 years ago

Sigh...

zty5678 commented 8 years ago

It seems that UIL was using MarkableInputStream before and UIL uses a ContentLengthInputStream now. See https://github.com/nostra13/Android-Universal-Image-Loader/commit/4f3172262de460ad4b59d86f036c8a38aec9ee93 and https://github.com/nostra13/Android-Universal-Image-Loader/tree/master/library/src/main/java/com/nostra13/universalimageloader/core/assist

sathvik87 commented 8 years ago

+1 Having same issue on Moto E, using 2.5.2

feitengbing2014 commented 8 years ago

have same issue on huawei p8, 2.5.2

jaredrummler commented 8 years ago

Same issue on Moto X Style. Picasso 2.5.2. Android 5.1.1. Loading from disk.

EvilsoulM commented 8 years ago

have same issue on oppo R7.Picasso 2.5.2 android 5.1.1. Loading from disk

anilshar commented 8 years ago

Please fix this issue, I wrote a good amount of code for my app and later struck with this issue. I have to now move to Glide.

JakeWharton commented 8 years ago

Pull requests are welcome.

On Tue, Nov 10, 2015 at 12:59 PM Anil Sharma notifications@github.com wrote:

Please fix this issue, I wrote a good amount of code for my app and later struck with this issue. I have to now move to Glide.

— Reply to this email directly or view it on GitHub https://github.com/square/picasso/issues/364#issuecomment-155514444.

vedant1811 commented 8 years ago

Is there a work around for this? Occurring on some devices only (like old Moto G- android 4.4.4)

JohnWowUs commented 8 years ago

PR #1035 and PR #1219 have been proposed to fix this. One of these may be merged soon or you can roll your own.

vedant1811 commented 8 years ago

@JohnWowUs I'll wait :+1:

ubuntudroid commented 8 years ago

What's the status here? Eagerly waiting to update our app to the latest version, but this issue keeps us from doing so. PR #1035 looks good.

lukaspili commented 8 years ago

Experiencing this issue with several images as well: Android 6 + 2.5.2.