YAACC - UPNP Client and Server
Loading...
Searching...
No Matches
de.yaacc.util.image.BitmapSampling Class Reference

Shared helpers for decoding a bitmap downsampled to a target size instead of at native resolution (issue #285 - a high-resolution source image decoded at full size, then scaled down afterward, allocates and decodes every pixel of the original for no benefit once it's about to be shrunk). More...

Collaboration diagram for de.yaacc.util.image.BitmapSampling:
Collaboration graph

Static Public Member Functions

static byte[] readAllBytes (InputStream in) throws IOException
 Reads an entire stream into memory.
 
static byte[] readAllBytes (InputStream in, int maxBytes) throws IOException
 As readAllBytes(InputStream), but for a source that can not be trusted to end (an address that comes from another device): reading stops with an exception when the stream is longer than maxBytes.
 
static int computeInSampleSize (BitmapFactory.Options options, int reqWidth, int reqHeight)
 The standard Android pattern for sizing a downsampled decode: the smallest power-of-two inSampleSize whose resulting dimensions still cover the requested size.
 
static int computeInSampleSizeForMaxDimension (BitmapFactory.Options options, int maxDimension)
 Like computeInSampleSize, but for capping a maximum dimension rather than guaranteeing a minimum one - these are NOT interchangeable.
 

Detailed Description

Shared helpers for decoding a bitmap downsampled to a target size instead of at native resolution (issue #285 - a high-resolution source image decoded at full size, then scaled down afterward, allocates and decodes every pixel of the original for no benefit once it's about to be shrunk).

Used by both the full-screen image viewer (ImageFragment) and the thumbnail/icon loading path (ImageDownloader), which independently had the same underlying flaw.

Member Function Documentation

◆ computeInSampleSize()

static int de.yaacc.util.image.BitmapSampling.computeInSampleSize ( BitmapFactory.Options options,
int reqWidth,
int reqHeight )
static

The standard Android pattern for sizing a downsampled decode: the smallest power-of-two inSampleSize whose resulting dimensions still cover the requested size.

options must already have been populated by a bounds-only decode (inJustDecodeBounds =
true
) of the same image. See "Loading Large Bitmaps Efficiently" in the Android developer guide.

reqWidth/reqHeight of 0 or less (e.g. a caller passing an unmeasured View's getWidth()/
getHeight()
) are clamped up to 1: with an unclamped 0, the loop's >= 0 condition is unconditionally true for any non-negative inSampleSize, so it never terminates naturally and just doubles inSampleSize until it overflows - a last-resort safety net, not a substitute for callers passing a real target size (the resulting bitmap would still be near-unusably tiny, just not a crash).

◆ computeInSampleSizeForMaxDimension()

static int de.yaacc.util.image.BitmapSampling.computeInSampleSizeForMaxDimension ( BitmapFactory.Options options,
int maxDimension )
static

Like computeInSampleSize, but for capping a maximum dimension rather than guaranteeing a minimum one - these are NOT interchangeable.

computeInSampleSize's loop condition is AND: it keeps downsampling only while BOTH halved dimensions still exceed the target, which is correct when the target is a small view size you want the decode to at least cover (the view crops/scales the rest). Capping a maximum dimension needs the opposite - keep downsampling while EITHER dimension still exceeds the cap - otherwise a non-square image whose shorter side already happens to be within roughly 2x of the cap stops the loop immediately regardless of how far the longer side overshoots it, leaving the image undownsampled (this was issue #285's full-screen-viewer fix initially reusing computeInSampleSize for this purpose - for an 8160x6144 photo capped at 4096, height/2 (3072) is already below 4096, so the AND condition is false from the first check and inSampleSize never advances past 1, reproducing the original full-resolution-decode crash for any photo with a side in (cap, 2*cap) - the common case for modern phone cameras, not an edge case).

Referenced by de.yaacc.player.AVTransportPlayer.AVTransportPlayer().

Here is the caller graph for this function:

◆ readAllBytes() [1/2]

static byte[] de.yaacc.util.image.BitmapSampling.readAllBytes ( InputStream in) throws IOException
static

Reads an entire stream into memory.

Decoding a bitmap downsampled (see computeInSampleSize) needs two passes over the same image data (a bounds-only pass, then the real decode), and most sources here (network streams in particular) can't be rewound/read twice - buffering the compressed bytes once is far cheaper than the decoded bitmap they produce, so this is a net memory reduction versus decoding directly from a live stream, not a cost.

Referenced by de.yaacc.util.image.BitmapSampling.readAllBytes().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ readAllBytes() [2/2]

static byte[] de.yaacc.util.image.BitmapSampling.readAllBytes ( InputStream in,
int maxBytes ) throws IOException
static

As readAllBytes(InputStream), but for a source that can not be trusted to end (an address that comes from another device): reading stops with an exception when the stream is longer than maxBytes.

Exceptions
IOExceptionif the stream has more than maxBytes bytes

The documentation for this class was generated from the following file: