24SkISize SkSampledCodec::accountForNativeScaling(
int* sampleSizePtr,
int* nativeSampleSize)
const {
26 int sampleSize = *sampleSizePtr;
29 if (nativeSampleSize) {
30 *nativeSampleSize = 1;
49 const int sampleSizes[] = { 8, 4, 2 };
50 for (
int supportedSampleSize : sampleSizes) {
52 SkTDivMod(sampleSize, supportedSampleSize, &actualSampleSize, &remainder);
60 *sampleSizePtr = actualSampleSize;
61 if (nativeSampleSize) {
62 *nativeSampleSize = supportedSampleSize;
69 return preSampledSize;
73 const SkISize size = this->accountForNativeScaling(&sampleSize);
81 if (!subset || subset->
size() == this->codec()->dimensions()) {
82 if (this->
codec()->dimensionsSupported(
info.dimensions())) {
87 return this->sampledDecode(
info, pixels, rowBytes,
options);
91 int sampleSize =
options.fSampleSize;
93 if (!this->
codec()->dimensionsSupported(scaledSize)) {
95 return this->sampledDecode(
info, pixels, rowBytes,
options);
99 int scaledSubsetX = subset->
x() / sampleSize;
100 int scaledSubsetY = subset->
y() / sampleSize;
101 int scaledSubsetWidth =
info.width();
102 int scaledSubsetHeight =
info.height();
113 scaledSubsetWidth, scaledSubsetHeight);
114 subsetOptions.
fSubset = &incrementalSubset;
116 scaledInfo, pixels, rowBytes, &subsetOptions);
126 this->
codec()->fillIncompleteImage(scaledInfo, pixels, rowBytes,
127 options.fZeroInitialized, scaledSubsetHeight, rowsDecoded);
140 subsetOptions.
fSubset = &scanlineSubset;
153 if (!this->
codec()->skipScanlines(scaledSubsetY)) {
154 this->
codec()->fillIncompleteImage(info, pixels, rowBytes,
options.fZeroInitialized,
155 scaledSubsetHeight, 0);
159 int decodedLines = this->
codec()->
getScanlines(pixels, scaledSubsetHeight, rowBytes);
160 if (decodedLines != scaledSubsetHeight) {
168 size_t rowBytes,
const AndroidOptions&
options) {
173 int sampleSize =
options.fSampleSize;
174 int nativeSampleSize;
175 SkISize nativeSize = this->accountForNativeScaling(&sampleSize, &nativeSampleSize);
180 int subsetWidth = nativeSize.
width();
181 int subsetHeight = nativeSize.
height();
191 const int subsetX = subsetPtr->
x() / nativeSampleSize;
192 subsetY = subsetPtr->
y() / nativeSampleSize;
198 subset.
setXYWH(subsetX, 0, subsetWidth, nativeSize.
height());
204 const int sampleX = subsetWidth /
info.width();
205 const int sampleY = subsetHeight /
info.height();
208 const int startY = samplingOffsetY + subsetY;
209 const int dstHeight =
info.height();
217 AndroidOptions incrementalOptions =
options;
220 incrementalSubset.
fTop = subsetY;
221 incrementalSubset.
fBottom = subsetY + subsetHeight;
224 incrementalOptions.fSubset = &incrementalSubset;
227 pixels, rowBytes, &incrementalOptions);
251 this->
codec()->fillIncompleteImage(info, pixels, rowBytes,
options.fZeroInitialized,
263 AndroidOptions sampledOptions =
options;
265 sampledOptions.fSubset = ⊂
287 switch(this->
codec()->getScanlineOrder()) {
289 if (!this->
codec()->skipScanlines(startY)) {
290 this->
codec()->fillIncompleteImage(info, pixels, rowBytes,
options.fZeroInitialized,
294 void* pixelPtr = pixels;
295 for (
int y = 0;
y < dstHeight;
y++) {
296 if (1 != this->
codec()->getScanlines(pixelPtr, 1, rowBytes)) {
297 this->
codec()->fillIncompleteImage(info, pixels, rowBytes,
298 options.fZeroInitialized, dstHeight,
y + 1);
301 if (
y < dstHeight - 1) {
302 if (!this->
codec()->skipScanlines(sampleY - 1)) {
303 this->
codec()->fillIncompleteImage(info, pixels, rowBytes,
304 options.fZeroInitialized, dstHeight,
y + 1);
308 pixelPtr = SkTAddOffset<void>(pixelPtr, rowBytes);
316 for (
y = 0;
y < nativeSize.
height();
y++) {
319 void* pixelPtr = SkTAddOffset<void>(pixels,
321 if (1 != this->
codec()->getScanlines(pixelPtr, 1, rowBytes)) {
325 if (!this->
codec()->skipScanlines(1)) {
331 if (nativeSize.
height() ==
y) {
338 for (;
y < nativeSize.
height();
y++) {
344 void* rowPtr = SkTAddOffset<void>(pixels, rowBytes *
get_dst_coord(srcY, sampleY));
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
static bool is_coord_necessary(int srcCoord, int sampleFactor, int scaledDim)
static int get_dst_coord(int srcCoord, int sampleFactor)
static float get_scale_from_sample_size(int sampleSize)
static int get_scaled_dimension(int srcDimension, int sampleSize)
static int get_start_coord(int sampleFactor)
void SkTDivMod(In numer, In denom, Out *div, Out *mod)
SkEncodedImageFormat getEncodedFormat() const
SkISize getSampledDimensions(int sampleSize) const
int getScanlines(void *dst, int countLines, size_t rowBytes)
SkISize dimensions() const
Result startScanlineDecode(const SkImageInfo &dstInfo, const Options *options)
@ kBottomUp_SkScanlineOrder
@ kTopDown_SkScanlineOrder
Result getPixels(const SkImageInfo &info, void *pixels, size_t rowBytes, const Options *)
virtual SkSampler * getSampler(bool)
Result startIncrementalDecode(const SkImageInfo &dstInfo, void *dst, size_t rowBytes, const Options *)
Result incrementalDecode(int *rowsDecoded=nullptr)
SkISize getScaledDimensions(float desiredScale) const
int outputScanline(int inputScanline) const
SkSampledCodec(SkCodec *)
SkISize onGetSampledDimensions(int sampleSize) const override
SkCodec::Result onGetAndroidPixels(const SkImageInfo &info, void *pixels, size_t rowBytes, const AndroidOptions &options) override
void setSampleY(int sampleY)
int setSampleX(int sampleX)
static void Fill(const SkImageInfo &info, void *dst, size_t rowBytes, SkCodec::ZeroInitialized zeroInit)
constexpr int32_t x() const
constexpr int32_t y() const
int32_t fBottom
larger y-axis bounds
constexpr SkISize size() const
constexpr int32_t height() const
int32_t fTop
smaller y-axis bounds
constexpr int32_t width() const
void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height)
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
int32_t fLeft
smaller x-axis bounds
int32_t fRight
larger x-axis bounds
static constexpr SkISize Make(int32_t w, int32_t h)
constexpr int32_t width() const
constexpr int32_t height() const
SkImageInfo makeWH(int newWidth, int newHeight) const
SkImageInfo makeDimensions(SkISize newSize) const