uint32_t* swizzleDst = (uint32_t*) dst;
size_t decodeDstRowBytes = rowBytes;
size_t swizzleDstRowBytes = rowBytes;
+ int dstWidth = dstInfo.width();
if (fSwizzleSrcRow && fColorXformSrcRow) {
decodeDst = (JSAMPLE*) fSwizzleSrcRow;
swizzleDst = fColorXformSrcRow;
decodeDstRowBytes = 0;
swizzleDstRowBytes = 0;
+ dstWidth = fSwizzler->swizzleWidth();
} else if (fColorXformSrcRow) {
decodeDst = (JSAMPLE*) fColorXformSrcRow;
swizzleDst = fColorXformSrcRow;
} else if (fSwizzleSrcRow) {
decodeDst = (JSAMPLE*) fSwizzleSrcRow;
decodeDstRowBytes = 0;
+ dstWidth = fSwizzler->swizzleWidth();
}
for (int y = 0; y < count; y++) {
}
if (fColorXform) {
- fColorXform->apply(dst, swizzleDst, dstInfo.width(), dstInfo.colorType(),
- kOpaque_SkAlphaType);
+ fColorXform->apply(dst, swizzleDst, dstWidth, dstInfo.colorType(), kOpaque_SkAlphaType);
dst = SkTAddOffset<void>(dst, rowBytes);
}
}
void SkJpegCodec::allocateStorage(const SkImageInfo& dstInfo) {
+ int dstWidth = dstInfo.width();
+
size_t swizzleBytes = 0;
if (fSwizzler) {
swizzleBytes = get_row_bytes(fDecoderMgr->dinfo());
+ dstWidth = fSwizzler->swizzleWidth();
SkASSERT(!fColorXform || SkIsAlign4(swizzleBytes));
}
size_t xformBytes = 0;
if (kRGBA_F16_SkColorType == dstInfo.colorType()) {
SkASSERT(fColorXform);
- xformBytes = dstInfo.width() * sizeof(uint32_t);
+ xformBytes = dstWidth * sizeof(uint32_t);
}
size_t totalBytes = swizzleBytes + xformBytes;
}
}
-void SkPngCodec::allocateStorage(const SkImageInfo& dstInfo) {
- const int width = this->getInfo().width();
- size_t colorXformBytes = fColorXform ? width * sizeof(uint32_t) : 0;
+void SkPngCodec::allocateStorage() {
+ size_t colorXformBytes = fColorXform ? fSwizzler->swizzleWidth() * sizeof(uint32_t) : 0;
fStorage.reset(SkAlign4(fSrcRowBytes) + colorXformBytes);
fSwizzlerSrcRow = fStorage.get();
return kInvalidConversion;
}
- this->allocateStorage(dstInfo);
+ this->allocateStorage();
return kSuccess;
}
fSwizzler->swizzle(swizzlerDstRow, fSwizzlerSrcRow);
if (fColorXform) {
- fColorXform->apply(dst, (const uint32_t*) swizzlerDstRow, dstInfo.width(),
+ fColorXform->apply(dst, (const uint32_t*) swizzlerDstRow, fSwizzler->swizzleWidth(),
dstInfo.colorType(), xformAlphaType);
dst = SkTAddOffset<void>(dst, rowBytes);
}
return kInvalidConversion;
}
- this->allocateStorage(dstInfo);
+ this->allocateStorage();
fCanSkipRewind = true;
return SkCodec::kSuccess;
}
if (fColorXform) {
if (fColorXform) {
- fColorXform->apply(dst, (const uint32_t*) swizzlerDstRow, dstInfo.width(),
- dstInfo.colorType(), xformAlphaType);
+ fColorXform->apply(dst, (const uint32_t*) swizzlerDstRow,
+ fSwizzler->swizzleWidth(), dstInfo.colorType(),
+ xformAlphaType);
dst = SkTAddOffset<void>(dst, rowBytes);
}
}
return kUnimplemented;
}
- this->allocateStorage(dstInfo);
+ this->allocateStorage();
int count = this->readRows(dstInfo, dst, rowBytes, dstInfo.height(), 0);
if (count > dstInfo.height()) {
*rowsDecoded = count;
SkASSERT(fSwizzler);
return fSwizzler;
}
- void allocateStorage(const SkImageInfo& dstInfo);
+ void allocateStorage();
virtual int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count,
int startRow) = 0;
*/
int sampleX() const { return fSampleX; }
+ /**
+ * Returns the actual number of pixels written to destination memory, taking
+ * scaling, subsetting, and partial frames into account.
+ */
+ int swizzleWidth() const { return fSwizzleWidth; }
+
private:
/**
REPORTER_ASSERT(r, SkCodec::kSuccess == result);
}
+static void check_color_xform(skiatest::Reporter* r, const char* path) {
+ SkAutoTDelete<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(resource(path)));
+
+ SkAndroidCodec::AndroidOptions opts;
+ opts.fSampleSize = 3;
+ const int subsetWidth = codec->getInfo().width() / 2;
+ const int subsetHeight = codec->getInfo().height() / 2;
+ SkIRect subset = SkIRect::MakeWH(subsetWidth, subsetHeight);
+ opts.fSubset = ⊂
+
+ const int dstWidth = subsetWidth / opts.fSampleSize;
+ const int dstHeight = subsetHeight / opts.fSampleSize;
+ sk_sp<SkData> data = SkData::MakeFromFileName(
+ GetResourcePath("icc_profiles/HP_ZR30w.icc").c_str());
+ sk_sp<SkColorSpace> colorSpace = SkColorSpace::NewICC(data->data(), data->size());
+ SkImageInfo dstInfo = codec->getInfo().makeWH(dstWidth, dstHeight)
+ .makeColorType(kN32_SkColorType)
+ .makeColorSpace(colorSpace);
+
+ size_t rowBytes = dstInfo.minRowBytes();
+ SkAutoMalloc pixelStorage(dstInfo.getSafeSize(rowBytes));
+ SkCodec::Result result = codec->getAndroidPixels(dstInfo, pixelStorage.get(), rowBytes, &opts);
+ REPORTER_ASSERT(r, SkCodec::kSuccess == result);
+}
+
+DEF_TEST(Codec_ColorXform, r) {
+ check_color_xform(r, "mandrill_512_q075.jpg");
+ check_color_xform(r, "mandrill_512.png");
+}
+
DEF_TEST(Codec_Png565, r) {
// Create an arbitrary 565 bitmap.
const char* path = "mandrill_512_q075.jpg";