Reland "Remove support for decoding to kIndex_8"
Original change's description: > > Remove support for decoding to kIndex_8 > > > > Fix up callsites, and remove tests that no longer make sense. > > > > Bug: skia:6828 > > Change-Id: I2548c4b7528b7b1be7412563156f27b52c9d4295 > > Reviewed-on: https://skia-review.googlesource.com/21664 > > Reviewed-by: Derek Sollenberger <djsollen@google.com> > > Commit-Queue: Leon Scroggins <scroggo@google.com> > > TBR=djsollen@google.com,scroggo@google.com > > Change-Id: I1bc669441f250690884e75a9a61427fdf75c6907 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: skia:6828 > Reviewed-on: https://skia-review.googlesource.com/22120 > Reviewed-by: Leon Scroggins <scroggo@google.com> > Commit-Queue: Leon Scroggins <scroggo@google.com> TBR=djsollen@google.com,scroggo@google.com Bug: skia:6828 Change-Id: I36ff5a11c529d29e8adc95f43b8edc6fd1dbf5b8 Reviewed-on: https://skia-review.googlesource.com/22320 Reviewed-by: Leon Scroggins <scroggo@google.com> Commit-Queue: Leon Scroggins <scroggo@google.com>
This commit is contained in:
parent
f778eb2f51
commit
571b30f611
@ -51,20 +51,17 @@ void CodecBench::onDelayedSetup() {
|
||||
|
||||
void CodecBench::onDraw(int n, SkCanvas* canvas) {
|
||||
std::unique_ptr<SkCodec> codec;
|
||||
SkPMColor colorTable[256];
|
||||
int colorCount;
|
||||
SkCodec::Options options;
|
||||
if (FLAGS_zero_init) {
|
||||
options.fZeroInitialized = SkCodec::kYes_ZeroInitialized;
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
colorCount = 256;
|
||||
codec.reset(SkCodec::NewFromData(fData));
|
||||
#ifdef SK_DEBUG
|
||||
const SkCodec::Result result =
|
||||
#endif
|
||||
codec->getPixels(fInfo, fPixelStorage.get(), fInfo.minRowBytes(),
|
||||
&options, colorTable, &colorCount);
|
||||
&options);
|
||||
SkASSERT(result == SkCodec::kSuccess
|
||||
|| result == SkCodec::kIncompleteInput);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ inline const char* color_type_to_str(SkColorType colorType) {
|
||||
case kGray_8_SkColorType:
|
||||
return "Gray8";
|
||||
case kIndex_8_SkColorType:
|
||||
SkASSERT(false);
|
||||
return "Index8";
|
||||
case kAlpha_8_SkColorType:
|
||||
return "Alpha8";
|
||||
|
@ -630,7 +630,6 @@ public:
|
||||
if (!FLAGS_simpleCodec) {
|
||||
fColorTypes.push_back(kRGB_565_SkColorType);
|
||||
fColorTypes.push_back(kAlpha_8_SkColorType);
|
||||
fColorTypes.push_back(kIndex_8_SkColorType);
|
||||
fColorTypes.push_back(kGray_8_SkColorType);
|
||||
}
|
||||
}
|
||||
@ -859,13 +858,8 @@ public:
|
||||
const size_t rowBytes = info.minRowBytes();
|
||||
SkAutoMalloc storage(info.getSafeSize(rowBytes));
|
||||
|
||||
// Used if fCurrentColorType is kIndex_8_SkColorType
|
||||
int colorCount = 256;
|
||||
SkPMColor colors[256];
|
||||
|
||||
const SkCodec::Result result = codec->getPixels(
|
||||
info, storage.get(), rowBytes, nullptr, colors,
|
||||
&colorCount);
|
||||
info, storage.get(), rowBytes);
|
||||
switch (result) {
|
||||
case SkCodec::kSuccess:
|
||||
case SkCodec::kIncompleteInput:
|
||||
|
@ -343,12 +343,9 @@ static void premultiply_if_necessary(SkBitmap& bitmap) {
|
||||
SkOpts::RGBA_to_rgbA(row, row, bitmap.width());
|
||||
}
|
||||
break;
|
||||
case kIndex_8_SkColorType: {
|
||||
SkColorTable* colorTable = bitmap.getColorTable();
|
||||
SkPMColor* colorPtr = const_cast<SkPMColor*>(colorTable->readColors());
|
||||
SkOpts::RGBA_to_rgbA(colorPtr, colorPtr, colorTable->count());
|
||||
case kIndex_8_SkColorType:
|
||||
SkASSERT(false);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// No need to premultiply kGray or k565 outputs.
|
||||
break;
|
||||
@ -400,11 +397,10 @@ static bool get_decode_info(SkImageInfo* decodeInfo, SkColorType canvasColorType
|
||||
}
|
||||
|
||||
static void draw_to_canvas(SkCanvas* canvas, const SkImageInfo& info, void* pixels, size_t rowBytes,
|
||||
SkPMColor* colorPtr, int colorCount, CodecSrc::DstColorType dstColorType,
|
||||
CodecSrc::DstColorType dstColorType,
|
||||
SkScalar left = 0, SkScalar top = 0) {
|
||||
sk_sp<SkColorTable> colorTable(new SkColorTable(colorPtr, colorCount));
|
||||
SkBitmap bitmap;
|
||||
bitmap.installPixels(info, pixels, rowBytes, colorTable.get(), nullptr, nullptr);
|
||||
bitmap.installPixels(info, pixels, rowBytes);
|
||||
premultiply_if_necessary(bitmap);
|
||||
swap_rb_if_necessary(bitmap, dstColorType);
|
||||
canvas->drawBitmap(bitmap, left, top);
|
||||
@ -457,8 +453,6 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
const size_t rowBytes = size.width() * bpp;
|
||||
const size_t safeSize = decodeInfo.getSafeSize(rowBytes);
|
||||
SkAutoMalloc pixels(safeSize);
|
||||
SkPMColor colorPtr[256];
|
||||
int colorCount = 256;
|
||||
|
||||
SkCodec::Options options;
|
||||
options.fPremulBehavior = canvas->imageInfo().colorSpace() ?
|
||||
@ -504,8 +498,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
options.fPriorFrame = SkCodec::kNone;
|
||||
}
|
||||
SkCodec::Result result = codec->getPixels(decodeInfo, pixels.get(),
|
||||
rowBytes, &options,
|
||||
colorPtr, &colorCount);
|
||||
rowBytes, &options);
|
||||
if (SkCodec::kInvalidInput == result && i > 0) {
|
||||
// Some of our test images have truncated later frames. Treat that
|
||||
// the same as incomplete.
|
||||
@ -531,8 +524,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
const int xTranslate = (i % factor) * decodeInfo.width();
|
||||
const int yTranslate = (i / factor) * decodeInfo.height();
|
||||
canvas->translate(SkIntToScalar(xTranslate), SkIntToScalar(yTranslate));
|
||||
draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes,
|
||||
colorPtr, colorCount, fDstColorType);
|
||||
draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes, fDstColorType);
|
||||
if (result != SkCodec::kSuccess) {
|
||||
return "";
|
||||
}
|
||||
@ -554,8 +546,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
}
|
||||
case kCodecZeroInit_Mode:
|
||||
case kCodec_Mode: {
|
||||
switch (codec->getPixels(decodeInfo, pixels.get(), rowBytes, &options,
|
||||
colorPtr, &colorCount)) {
|
||||
switch (codec->getPixels(decodeInfo, pixels.get(), rowBytes, &options)) {
|
||||
case SkCodec::kSuccess:
|
||||
// We consider these to be valid, since we should still decode what is
|
||||
// available.
|
||||
@ -567,8 +558,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str());
|
||||
}
|
||||
|
||||
draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes, colorPtr, colorCount,
|
||||
fDstColorType);
|
||||
draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes, fDstColorType);
|
||||
break;
|
||||
}
|
||||
case kScanline_Mode: {
|
||||
@ -589,7 +579,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
bool useOldScanlineMethod = !useIncremental && !ico;
|
||||
if (useIncremental || ico) {
|
||||
if (SkCodec::kSuccess == codec->startIncrementalDecode(decodeInfo, dst,
|
||||
rowBytes, &options, colorPtr, &colorCount)) {
|
||||
rowBytes, &options)) {
|
||||
int rowsDecoded;
|
||||
auto result = codec->incrementalDecode(&rowsDecoded);
|
||||
if (SkCodec::kIncompleteInput == result || SkCodec::kErrorInInput == result) {
|
||||
@ -609,8 +599,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
}
|
||||
|
||||
if (useOldScanlineMethod) {
|
||||
if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL, colorPtr,
|
||||
&colorCount)) {
|
||||
if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo)) {
|
||||
return "Could not start scanline decoder";
|
||||
}
|
||||
|
||||
@ -624,7 +613,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
}
|
||||
}
|
||||
|
||||
draw_to_canvas(canvas, bitmapInfo, dst, rowBytes, colorPtr, colorCount, fDstColorType);
|
||||
draw_to_canvas(canvas, bitmapInfo, dst, rowBytes, fDstColorType);
|
||||
break;
|
||||
}
|
||||
case kStripe_Mode: {
|
||||
@ -636,8 +625,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
void* dst = pixels.get();
|
||||
|
||||
// Decode odd stripes
|
||||
if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, &options, colorPtr,
|
||||
&colorCount)) {
|
||||
if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, &options)) {
|
||||
return "Could not start scanline decoder";
|
||||
}
|
||||
|
||||
@ -662,8 +650,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
}
|
||||
|
||||
// Decode even stripes
|
||||
const SkCodec::Result startResult = codec->startScanlineDecode(decodeInfo, nullptr,
|
||||
colorPtr, &colorCount);
|
||||
const SkCodec::Result startResult = codec->startScanlineDecode(decodeInfo);
|
||||
if (SkCodec::kSuccess != startResult) {
|
||||
return "Failed to restart scanline decoder with same parameters.";
|
||||
}
|
||||
@ -681,7 +668,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
}
|
||||
}
|
||||
|
||||
draw_to_canvas(canvas, bitmapInfo, dst, rowBytes, colorPtr, colorCount, fDstColorType);
|
||||
draw_to_canvas(canvas, bitmapInfo, dst, rowBytes, fDstColorType);
|
||||
break;
|
||||
}
|
||||
case kCroppedScanline_Mode: {
|
||||
@ -695,16 +682,14 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
for (int x = 0; x < width; x += tileSize) {
|
||||
subset = SkIRect::MakeXYWH(x, 0, SkTMin(tileSize, width - x), height);
|
||||
options.fSubset = ⊂
|
||||
if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, &options,
|
||||
colorPtr, &colorCount)) {
|
||||
if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, &options)) {
|
||||
return "Could not start scanline decoder.";
|
||||
}
|
||||
|
||||
codec->getScanlines(SkTAddOffset<void>(pixels.get(), x * bpp), height, rowBytes);
|
||||
}
|
||||
|
||||
draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes, colorPtr, colorCount,
|
||||
fDstColorType);
|
||||
draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes, fDstColorType);
|
||||
break;
|
||||
}
|
||||
case kSubset_Mode: {
|
||||
@ -747,7 +732,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
SkImageInfo subsetBitmapInfo = bitmapInfo.makeWH(scaledW, scaledH);
|
||||
size_t subsetRowBytes = subsetBitmapInfo.minRowBytes();
|
||||
const SkCodec::Result result = codec->getPixels(decodeInfo, dst, subsetRowBytes,
|
||||
&options, colorPtr, &colorCount);
|
||||
&options);
|
||||
switch (result) {
|
||||
case SkCodec::kSuccess:
|
||||
case SkCodec::kErrorInInput:
|
||||
@ -759,9 +744,8 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
|
||||
x, y, decodeInfo.width(), decodeInfo.height(),
|
||||
fPath.c_str(), W, H, result);
|
||||
}
|
||||
draw_to_canvas(canvas, subsetBitmapInfo, dst, subsetRowBytes, colorPtr,
|
||||
colorCount, fDstColorType, SkIntToScalar(left),
|
||||
SkIntToScalar(top));
|
||||
draw_to_canvas(canvas, subsetBitmapInfo, dst, subsetRowBytes, fDstColorType,
|
||||
SkIntToScalar(left), SkIntToScalar(top));
|
||||
|
||||
// translate by the scaled height.
|
||||
top += decodeInfo.height();
|
||||
@ -865,8 +849,6 @@ Error AndroidCodecSrc::draw(SkCanvas* canvas) const {
|
||||
int bpp = SkColorTypeBytesPerPixel(decodeInfo.colorType());
|
||||
size_t rowBytes = size.width() * bpp;
|
||||
SkAutoMalloc pixels(size.height() * rowBytes);
|
||||
SkPMColor colorPtr[256];
|
||||
int colorCount = 256;
|
||||
|
||||
SkBitmap bitmap;
|
||||
SkImageInfo bitmapInfo = decodeInfo;
|
||||
@ -878,8 +860,6 @@ Error AndroidCodecSrc::draw(SkCanvas* canvas) const {
|
||||
|
||||
// Create options for the codec.
|
||||
SkAndroidCodec::AndroidOptions options;
|
||||
options.fColorPtr = colorPtr;
|
||||
options.fColorCount = &colorCount;
|
||||
options.fSampleSize = fSampleSize;
|
||||
|
||||
switch (codec->getAndroidPixels(decodeInfo, pixels.get(), rowBytes, &options)) {
|
||||
@ -890,7 +870,7 @@ Error AndroidCodecSrc::draw(SkCanvas* canvas) const {
|
||||
default:
|
||||
return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str());
|
||||
}
|
||||
draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes, colorPtr, colorCount, fDstColorType);
|
||||
draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowBytes, fDstColorType);
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -1009,10 +989,8 @@ Error ImageGenSrc::draw(SkCanvas* canvas) const {
|
||||
return err;
|
||||
}
|
||||
|
||||
SkPMColor colorPtr[256];
|
||||
int colorCount = 256;
|
||||
set_bitmap_color_space(&decodeInfo);
|
||||
draw_to_canvas(canvas, decodeInfo, pixels.get(), rowBytes, colorPtr, colorCount,
|
||||
draw_to_canvas(canvas, decodeInfo, pixels.get(), rowBytes,
|
||||
CodecSrc::kGetFromCanvas_DstColorType);
|
||||
return "";
|
||||
}
|
||||
|
@ -202,32 +202,14 @@ static void fuzz_img(sk_sp<SkData> bytes, uint8_t scale, uint8_t mode) {
|
||||
}
|
||||
|
||||
SkImageInfo decodeInfo = codec->getInfo();
|
||||
if (4 == mode && decodeInfo.colorType() == kIndex_8_SkColorType) {
|
||||
// 4 means animated. Frames beyond the first cannot be decoded to
|
||||
// index 8.
|
||||
decodeInfo = decodeInfo.makeColorType(kN32_SkColorType);
|
||||
}
|
||||
|
||||
SkISize size = codec->getScaledDimensions(fscale);
|
||||
decodeInfo = decodeInfo.makeWH(size.width(), size.height());
|
||||
|
||||
// Construct a color table for the decode if necessary
|
||||
sk_sp<SkColorTable> colorTable(nullptr);
|
||||
SkPMColor* colorPtr = nullptr;
|
||||
int* colorCountPtr = nullptr;
|
||||
int maxColors = 256;
|
||||
if (kIndex_8_SkColorType == decodeInfo.colorType()) {
|
||||
SkPMColor colors[256];
|
||||
colorTable.reset(new SkColorTable(colors, maxColors));
|
||||
colorPtr = const_cast<SkPMColor*>(colorTable->readColors());
|
||||
colorCountPtr = &maxColors;
|
||||
}
|
||||
|
||||
SkBitmap bitmap;
|
||||
SkCodec::Options options;
|
||||
options.fZeroInitialized = SkCodec::kYes_ZeroInitialized;
|
||||
|
||||
if (!bitmap.tryAllocPixels(decodeInfo, colorTable, SkBitmap::kZeroPixels_AllocFlag)) {
|
||||
if (!bitmap.tryAllocPixels(decodeInfo, nullptr, SkBitmap::kZeroPixels_AllocFlag)) {
|
||||
SkDebugf("[terminated] Could not allocate memory. Image might be too large (%d x %d)",
|
||||
decodeInfo.width(), decodeInfo.height());
|
||||
return;
|
||||
@ -235,8 +217,7 @@ static void fuzz_img(sk_sp<SkData> bytes, uint8_t scale, uint8_t mode) {
|
||||
|
||||
switch (mode) {
|
||||
case 0: {//kCodecZeroInit_Mode, kCodec_Mode
|
||||
switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowBytes(), &options,
|
||||
colorPtr, colorCountPtr)) {
|
||||
switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowBytes(), &options)) {
|
||||
case SkCodec::kSuccess:
|
||||
SkDebugf("[terminated] Success!\n");
|
||||
break;
|
||||
@ -257,11 +238,10 @@ static void fuzz_img(sk_sp<SkData> bytes, uint8_t scale, uint8_t mode) {
|
||||
break;
|
||||
}
|
||||
case 1: {//kScanline_Mode
|
||||
if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL, colorPtr,
|
||||
colorCountPtr)) {
|
||||
SkDebugf("[terminated] Could not start scanline decoder\n");
|
||||
return;
|
||||
}
|
||||
if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo)) {
|
||||
SkDebugf("[terminated] Could not start scanline decoder\n");
|
||||
return;
|
||||
}
|
||||
|
||||
void* dst = bitmap.getAddr(0, 0);
|
||||
size_t rowBytes = bitmap.rowBytes();
|
||||
@ -285,8 +265,7 @@ static void fuzz_img(sk_sp<SkData> bytes, uint8_t scale, uint8_t mode) {
|
||||
const int numStripes = (height + stripeHeight - 1) / stripeHeight;
|
||||
|
||||
// Decode odd stripes
|
||||
if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL, colorPtr,
|
||||
colorCountPtr)
|
||||
if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo)
|
||||
|| SkCodec::kTopDown_SkScanlineOrder != codec->getScanlineOrder()) {
|
||||
// This mode was designed to test the new skip scanlines API in libjpeg-turbo.
|
||||
// Jpegs have kTopDown_SkScanlineOrder, and at this time, it is not interesting
|
||||
@ -309,8 +288,7 @@ static void fuzz_img(sk_sp<SkData> bytes, uint8_t scale, uint8_t mode) {
|
||||
}
|
||||
|
||||
// Decode even stripes
|
||||
const SkCodec::Result startResult = codec->startScanlineDecode(decodeInfo, nullptr,
|
||||
colorPtr, colorCountPtr);
|
||||
const SkCodec::Result startResult = codec->startScanlineDecode(decodeInfo);
|
||||
if (SkCodec::kSuccess != startResult) {
|
||||
SkDebugf("[terminated] Failed to restart scanline decoder with same parameters.\n");
|
||||
return;
|
||||
@ -369,13 +347,12 @@ static void fuzz_img(sk_sp<SkData> bytes, uint8_t scale, uint8_t mode) {
|
||||
SkTMax(1, SkScalarRoundToInt(preScaleW * fscale)),
|
||||
SkTMax(1, SkScalarRoundToInt(preScaleH * fscale)));
|
||||
size_t rowBytes = decodeInfo.minRowBytes();
|
||||
if (!subsetBm.installPixels(decodeInfo, pixels, rowBytes, colorTable.get(),
|
||||
nullptr, nullptr)) {
|
||||
if (!subsetBm.installPixels(decodeInfo, pixels, rowBytes)) {
|
||||
SkDebugf("[terminated] Could not install pixels.\n");
|
||||
return;
|
||||
}
|
||||
const SkCodec::Result result = codec->getPixels(decodeInfo, pixels, rowBytes,
|
||||
&opts, colorPtr, colorCountPtr);
|
||||
&opts);
|
||||
switch (result) {
|
||||
case SkCodec::kSuccess:
|
||||
case SkCodec::kIncompleteInput:
|
||||
|
@ -66,8 +66,7 @@ private:
|
||||
}
|
||||
|
||||
if (SkCodec::kSuccess != fCodec->getPixels(info, bm.getPixels(),
|
||||
bm.rowBytes(), &opts,
|
||||
nullptr, nullptr)) {
|
||||
bm.rowBytes(), &opts)) {
|
||||
SkDebugf("Could not getPixels for frame %i: %s", frameIndex, FLAGS_animatedGif[0]);
|
||||
return;
|
||||
}
|
||||
|
@ -22,8 +22,7 @@ sk_sp<SkImage> make_raster_image(const char* path, SkTransferFunctionBehavior be
|
||||
|
||||
SkCodec::Options opts;
|
||||
opts.fPremulBehavior = behavior;
|
||||
codec->getPixels(codec->getInfo(), bitmap.getPixels(), bitmap.rowBytes(), &opts,
|
||||
nullptr, nullptr);
|
||||
codec->getPixels(codec->getInfo(), bitmap.getPixels(), bitmap.rowBytes(), &opts);
|
||||
return SkImage::MakeFromBitmap(bitmap);
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
* @param requestedColorType Color type requested by the client
|
||||
*
|
||||
* |requestedColorType| may be overriden. We will default to kF16
|
||||
* for high precision images and kIndex8 for GIF and WBMP.
|
||||
* for high precision images.
|
||||
*
|
||||
* In the general case, if it is possible to decode to
|
||||
* |requestedColorType|, this returns |requestedColorType|.
|
||||
@ -154,8 +154,6 @@ public:
|
||||
AndroidOptions()
|
||||
: fZeroInitialized(SkCodec::kNo_ZeroInitialized)
|
||||
, fSubset(nullptr)
|
||||
, fColorPtr(nullptr)
|
||||
, fColorCount(nullptr)
|
||||
, fSampleSize(1)
|
||||
{}
|
||||
|
||||
@ -178,22 +176,6 @@ public:
|
||||
*/
|
||||
SkIRect* fSubset;
|
||||
|
||||
/**
|
||||
* If the client has requested a decode to kIndex8_SkColorType
|
||||
* (specified in the SkImageInfo), then the caller must provide
|
||||
* storage for up to 256 SkPMColor values in fColorPtr. On success,
|
||||
* the codec must copy N colors into that storage, (where N is the
|
||||
* logical number of table entries) and set fColorCount to N.
|
||||
*
|
||||
* If the client does not request kIndex8_SkColorType, then the last
|
||||
* two parameters may be NULL. If fColorCount is not null, it will be
|
||||
* set to 0.
|
||||
*
|
||||
* The default is NULL for both pointers.
|
||||
*/
|
||||
SkPMColor* fColorPtr;
|
||||
int* fColorCount;
|
||||
|
||||
/**
|
||||
* The client may provide an integer downscale factor for the decode.
|
||||
* The codec may implement this downscaling by sampling or another
|
||||
@ -224,14 +206,6 @@ public:
|
||||
* to scale or subset. If the codec cannot perform this
|
||||
* scaling or subsetting, it will return an error code.
|
||||
*
|
||||
* If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
|
||||
* SkPMColor values in options->fColorPtr. On success the codec must copy N colors into
|
||||
* that storage, (where N is the logical number of table entries) and set
|
||||
* options->fColorCount to N.
|
||||
*
|
||||
* If info is not kIndex8_SkColorType, options->fColorPtr and options->fColorCount may
|
||||
* be nullptr.
|
||||
*
|
||||
* The AndroidOptions object is also used to specify any requested scaling or subsetting
|
||||
* using options->fSampleSize and options->fSubset. If NULL, the defaults (as specified above
|
||||
* for AndroidOptions) are used.
|
||||
@ -247,10 +221,7 @@ public:
|
||||
|
||||
/**
|
||||
* Simplified version of getAndroidPixels() where we supply the default AndroidOptions as
|
||||
* specified above for AndroidOptions.
|
||||
*
|
||||
* This will return an error if the info is kIndex_8_SkColorType and also will not perform
|
||||
* any scaling or subsetting.
|
||||
* specified above for AndroidOptions. It will not perform any scaling or subsetting.
|
||||
*/
|
||||
SkCodec::Result getAndroidPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
|
||||
|
||||
|
@ -338,26 +338,19 @@ public:
|
||||
* reported by the codec, the color space transformation is
|
||||
* a no-op.
|
||||
*
|
||||
* If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
|
||||
* SkPMColor values in ctable. On success the generator must copy N colors into that storage,
|
||||
* (where N is the logical number of table entries) and set ctableCount to N.
|
||||
*
|
||||
* If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount
|
||||
* is not null, it will be set to 0.
|
||||
*
|
||||
* If a scanline decode is in progress, scanline mode will end, requiring the client to call
|
||||
* startScanlineDecode() in order to return to decoding scanlines.
|
||||
*
|
||||
* @return Result kSuccess, or another value explaining the type of failure.
|
||||
*/
|
||||
Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options*,
|
||||
SkPMColor ctable[], int* ctableCount);
|
||||
Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options*);
|
||||
|
||||
/**
|
||||
* Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType and
|
||||
* uses the default Options.
|
||||
* Simplified version of getPixels() that uses the default Options.
|
||||
*/
|
||||
Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
|
||||
Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
|
||||
return this->getPixels(info, pixels, rowBytes, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* If decoding to YUV is supported, this returns true. Otherwise, this
|
||||
@ -410,25 +403,13 @@ public:
|
||||
* if present, or the full image as described in dstInfo.
|
||||
* @param options Contains decoding options, including if memory is zero
|
||||
* initialized and whether to decode a subset.
|
||||
* @param ctable A pointer to a color table. When dstInfo.colorType() is
|
||||
* kIndex8, this should be non-NULL and have enough storage for 256
|
||||
* colors. The color table will be populated after decoding the palette.
|
||||
* @param ctableCount A pointer to the size of the color table. When
|
||||
* dstInfo.colorType() is kIndex8, this should be non-NULL. It will
|
||||
* be modified to the true size of the color table (<= 256) after
|
||||
* decoding the palette.
|
||||
* @return Enum representing success or reason for failure.
|
||||
*/
|
||||
Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
|
||||
const Options*, SkPMColor* ctable, int* ctableCount);
|
||||
|
||||
Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
|
||||
const Options* options) {
|
||||
return this->startIncrementalDecode(dstInfo, dst, rowBytes, options, nullptr, nullptr);
|
||||
}
|
||||
const Options*);
|
||||
|
||||
Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes) {
|
||||
return this->startIncrementalDecode(dstInfo, dst, rowBytes, nullptr, nullptr, nullptr);
|
||||
return this->startIncrementalDecode(dstInfo, dst, rowBytes, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -479,23 +460,16 @@ public:
|
||||
* those of getInfo, this implies a scale.
|
||||
* @param options Contains decoding options, including if memory is zero
|
||||
* initialized.
|
||||
* @param ctable A pointer to a color table. When dstInfo.colorType() is
|
||||
* kIndex8, this should be non-NULL and have enough storage for 256
|
||||
* colors. The color table will be populated after decoding the palette.
|
||||
* @param ctableCount A pointer to the size of the color table. When
|
||||
* dstInfo.colorType() is kIndex8, this should be non-NULL. It will
|
||||
* be modified to the true size of the color table (<= 256) after
|
||||
* decoding the palette.
|
||||
* @return Enum representing success or reason for failure.
|
||||
*/
|
||||
Result startScanlineDecode(const SkImageInfo& dstInfo, const Options* options,
|
||||
SkPMColor ctable[], int* ctableCount);
|
||||
Result startScanlineDecode(const SkImageInfo& dstInfo, const Options* options);
|
||||
|
||||
/**
|
||||
* Simplified version of startScanlineDecode() that asserts that info is NOT
|
||||
* kIndex8_SkColorType and uses the default Options.
|
||||
* Simplified version of startScanlineDecode() that uses the default Options.
|
||||
*/
|
||||
Result startScanlineDecode(const SkImageInfo& dstInfo);
|
||||
Result startScanlineDecode(const SkImageInfo& dstInfo) {
|
||||
return this->startScanlineDecode(dstInfo, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the next countLines scanlines into dst.
|
||||
@ -739,7 +713,6 @@ protected:
|
||||
*/
|
||||
virtual Result onGetPixels(const SkImageInfo& info,
|
||||
void* pixels, size_t rowBytes, const Options&,
|
||||
SkPMColor ctable[], int* ctableCount,
|
||||
int* rowsDecoded) = 0;
|
||||
|
||||
virtual bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const {
|
||||
@ -801,7 +774,6 @@ protected:
|
||||
* kN32_SkColorType: Transparent or Black, depending on the src alpha type
|
||||
* kRGB_565_SkColorType: Black
|
||||
* kGray_8_SkColorType: Black
|
||||
* kIndex_8_SkColorType: First color in color table
|
||||
*/
|
||||
virtual uint64_t onGetFillValue(const SkImageInfo& dstInfo) const;
|
||||
|
||||
@ -901,12 +873,12 @@ private:
|
||||
|
||||
// Methods for scanline decoding.
|
||||
virtual Result onStartScanlineDecode(const SkImageInfo& /*dstInfo*/,
|
||||
const Options& /*options*/, SkPMColor* /*ctable*/, int* /*ctableCount*/) {
|
||||
const Options& /*options*/) {
|
||||
return kUnimplemented;
|
||||
}
|
||||
|
||||
virtual Result onStartIncrementalDecode(const SkImageInfo& /*dstInfo*/, void*, size_t,
|
||||
const Options&, SkPMColor*, int*) {
|
||||
const Options&) {
|
||||
return kUnimplemented;
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@ public:
|
||||
case kPalette_Color: {
|
||||
SkAlphaType alphaType = (kOpaque_Alpha == fAlpha) ? kOpaque_SkAlphaType :
|
||||
kUnpremul_SkAlphaType;
|
||||
return SkImageInfo::Make(width, height, kIndex_8_SkColorType,
|
||||
return SkImageInfo::Make(width, height, kN32_SkColorType,
|
||||
alphaType, colorSpace);
|
||||
}
|
||||
case kRGB_Color:
|
||||
|
@ -71,16 +71,6 @@ private:
|
||||
void init(const SkPMColor* colors, int count);
|
||||
|
||||
friend class SkImageGenerator;
|
||||
friend class SkBitmapRegionCodec;
|
||||
// Only call if no other thread or cache has seen this table.
|
||||
void dangerous_overwriteColors(const SkPMColor newColors[], int count) {
|
||||
if (count < 0 || count > fCount) {
|
||||
sk_throw();
|
||||
}
|
||||
// assumes that f16BitCache nas NOT been initialized yet, so we don't try to update it
|
||||
memcpy(fColors, newColors, count * sizeof(SkPMColor));
|
||||
fCount = count; // update fCount, in case count is smaller
|
||||
}
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
@ -57,13 +57,7 @@ bool SkBitmapRegionCodec::decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocat
|
||||
SkImageInfo decodeInfo = SkImageInfo::Make(scaledSize.width(), scaledSize.height(),
|
||||
dstColorType, dstAlphaType, dstColorSpace);
|
||||
|
||||
// Construct a color table for the decode if necessary
|
||||
sk_sp<SkColorTable> colorTable(nullptr);
|
||||
int maxColors = 256;
|
||||
SkPMColor colors[256];
|
||||
if (kIndex_8_SkColorType == dstColorType) {
|
||||
colorTable.reset(new SkColorTable(colors, maxColors));
|
||||
}
|
||||
SkASSERT(dstColorType != kIndex_8_SkColorType);
|
||||
|
||||
// Initialize the destination bitmap
|
||||
int scaledOutX = 0;
|
||||
@ -90,7 +84,7 @@ bool SkBitmapRegionCodec::decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocat
|
||||
outInfo = outInfo.makeColorType(kAlpha_8_SkColorType).makeAlphaType(kPremul_SkAlphaType);
|
||||
}
|
||||
bitmap->setInfo(outInfo);
|
||||
if (!bitmap->tryAllocPixels(allocator, colorTable.get())) {
|
||||
if (!bitmap->tryAllocPixels(allocator, nullptr)) {
|
||||
SkCodecPrintf("Error: Could not allocate pixels.\n");
|
||||
return false;
|
||||
}
|
||||
@ -112,8 +106,6 @@ bool SkBitmapRegionCodec::decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocat
|
||||
SkAndroidCodec::AndroidOptions options;
|
||||
options.fSampleSize = sampleSize;
|
||||
options.fSubset = ⊂
|
||||
options.fColorPtr = colors;
|
||||
options.fColorCount = &maxColors;
|
||||
options.fZeroInitialized = zeroInit;
|
||||
void* dst = bitmap->getAddr(scaledOutX, scaledOutY);
|
||||
|
||||
@ -124,11 +116,6 @@ bool SkBitmapRegionCodec::decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocat
|
||||
return false;
|
||||
}
|
||||
|
||||
// Intialize the color table
|
||||
if (kIndex_8_SkColorType == dstColorType) {
|
||||
colorTable->dangerous_overwriteColors(colors, maxColors);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -622,19 +622,19 @@ int32_t SkBmpCodec::getDstRow(int32_t y, int32_t height) const {
|
||||
}
|
||||
|
||||
SkCodec::Result SkBmpCodec::prepareToDecode(const SkImageInfo& dstInfo,
|
||||
const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
|
||||
const SkCodec::Options& options) {
|
||||
if (!conversion_possible(dstInfo, this->getInfo()) ||
|
||||
!this->initializeColorXform(dstInfo, options.fPremulBehavior))
|
||||
{
|
||||
return kInvalidConversion;
|
||||
}
|
||||
|
||||
return this->onPrepareToDecode(dstInfo, options, inputColorPtr, inputColorCount);
|
||||
return this->onPrepareToDecode(dstInfo, options);
|
||||
}
|
||||
|
||||
SkCodec::Result SkBmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
|
||||
const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
|
||||
return prepareToDecode(dstInfo, options, inputColorPtr, inputColorCount);
|
||||
const SkCodec::Options& options) {
|
||||
return prepareToDecode(dstInfo, options);
|
||||
}
|
||||
|
||||
int SkBmpCodec::onGetScanlines(void* dst, int count, size_t rowBytes) {
|
||||
|
@ -91,20 +91,11 @@ protected:
|
||||
* @param dstInfo Contains output information. Height specifies
|
||||
* the total number of rows that will be decoded.
|
||||
* @param options Additonal options to pass to the decoder.
|
||||
* @param inputColorPtr Client-provided memory for a color table. Must
|
||||
* be enough for 256 colors. This will be
|
||||
* populated with colors if the encoded image uses
|
||||
* a color table.
|
||||
* @param inputColorCount If the encoded image uses a color table, this
|
||||
* will be set to the number of colors in the
|
||||
* color table.
|
||||
*/
|
||||
virtual SkCodec::Result onPrepareToDecode(const SkImageInfo& dstInfo,
|
||||
const SkCodec::Options& options, SkPMColor inputColorPtr[],
|
||||
int* inputColorCount) = 0;
|
||||
const SkCodec::Options& options) = 0;
|
||||
SkCodec::Result prepareToDecode(const SkImageInfo& dstInfo,
|
||||
const SkCodec::Options& options, SkPMColor inputColorPtr[],
|
||||
int* inputColorCount);
|
||||
const SkCodec::Options& options);
|
||||
|
||||
uint32_t* xformBuffer() const { return fXformBuffer.get(); }
|
||||
void resetXformBuffer(int count) { fXformBuffer.reset(new uint32_t[count]); }
|
||||
@ -144,8 +135,8 @@ private:
|
||||
|
||||
virtual bool skipRows(int count);
|
||||
|
||||
Result onStartScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options&,
|
||||
SkPMColor inputColorPtr[], int* inputColorCount) override;
|
||||
Result onStartScanlineDecode(const SkImageInfo& dstInfo,
|
||||
const SkCodec::Options&) override;
|
||||
|
||||
int onGetScanlines(void* dst, int count, size_t rowBytes) override;
|
||||
|
||||
|
@ -26,8 +26,6 @@ SkBmpMaskCodec::SkBmpMaskCodec(int width, int height, const SkEncodedInfo& info,
|
||||
SkCodec::Result SkBmpMaskCodec::onGetPixels(const SkImageInfo& dstInfo,
|
||||
void* dst, size_t dstRowBytes,
|
||||
const Options& opts,
|
||||
SkPMColor* inputColorPtr,
|
||||
int* inputColorCount,
|
||||
int* rowsDecoded) {
|
||||
if (opts.fSubset) {
|
||||
// Subsets are not supported.
|
||||
@ -38,7 +36,7 @@ SkCodec::Result SkBmpMaskCodec::onGetPixels(const SkImageInfo& dstInfo,
|
||||
return kInvalidScale;
|
||||
}
|
||||
|
||||
Result result = this->prepareToDecode(dstInfo, opts, inputColorPtr, inputColorCount);
|
||||
Result result = this->prepareToDecode(dstInfo, opts);
|
||||
if (kSuccess != result) {
|
||||
return result;
|
||||
}
|
||||
@ -52,7 +50,7 @@ SkCodec::Result SkBmpMaskCodec::onGetPixels(const SkImageInfo& dstInfo,
|
||||
}
|
||||
|
||||
SkCodec::Result SkBmpMaskCodec::onPrepareToDecode(const SkImageInfo& dstInfo,
|
||||
const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
|
||||
const SkCodec::Options& options) {
|
||||
if (this->colorXform()) {
|
||||
this->resetXformBuffer(dstInfo.width());
|
||||
}
|
||||
|
@ -38,12 +38,11 @@ public:
|
||||
protected:
|
||||
|
||||
Result onGetPixels(const SkImageInfo& dstInfo, void* dst,
|
||||
size_t dstRowBytes, const Options&, SkPMColor*,
|
||||
int*, int*) override;
|
||||
size_t dstRowBytes, const Options&,
|
||||
int*) override;
|
||||
|
||||
SkCodec::Result onPrepareToDecode(const SkImageInfo& dstInfo,
|
||||
const SkCodec::Options& options, SkPMColor inputColorPtr[],
|
||||
int* inputColorCount) override;
|
||||
const SkCodec::Options& options) override;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -34,15 +34,13 @@ SkBmpRLECodec::SkBmpRLECodec(int width, int height, const SkEncodedInfo& info, S
|
||||
SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo,
|
||||
void* dst, size_t dstRowBytes,
|
||||
const Options& opts,
|
||||
SkPMColor* inputColorPtr,
|
||||
int* inputColorCount,
|
||||
int* rowsDecoded) {
|
||||
if (opts.fSubset) {
|
||||
// Subsets are not supported.
|
||||
return kUnimplemented;
|
||||
}
|
||||
|
||||
Result result = this->prepareToDecode(dstInfo, opts, inputColorPtr, inputColorCount);
|
||||
Result result = this->prepareToDecode(dstInfo, opts);
|
||||
if (kSuccess != result) {
|
||||
return result;
|
||||
}
|
||||
@ -63,19 +61,13 @@ SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo,
|
||||
/*
|
||||
* Process the color table for the bmp input
|
||||
*/
|
||||
bool SkBmpRLECodec::createColorTable(SkColorType dstColorType, int* numColors) {
|
||||
bool SkBmpRLECodec::createColorTable(SkColorType dstColorType) {
|
||||
// Allocate memory for color table
|
||||
uint32_t colorBytes = 0;
|
||||
SkPMColor colorTable[256];
|
||||
if (this->bitsPerPixel() <= 8) {
|
||||
// Inform the caller of the number of colors
|
||||
uint32_t maxColors = 1 << this->bitsPerPixel();
|
||||
if (nullptr != numColors) {
|
||||
// We set the number of colors to maxColors in order to ensure
|
||||
// safe memory accesses. Otherwise, an invalid pixel could
|
||||
// access memory outside of our color table array.
|
||||
*numColors = maxColors;
|
||||
}
|
||||
// Don't bother reading more than maxColors.
|
||||
const uint32_t numColorsToRead =
|
||||
fNumColors == 0 ? maxColors : SkTMin(fNumColors, maxColors);
|
||||
@ -241,7 +233,7 @@ void SkBmpRLECodec::setRGBPixel(void* dst, size_t dstRowBytes,
|
||||
}
|
||||
|
||||
SkCodec::Result SkBmpRLECodec::onPrepareToDecode(const SkImageInfo& dstInfo,
|
||||
const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
|
||||
const SkCodec::Options& options) {
|
||||
// FIXME: Support subsets for scanline decodes.
|
||||
if (options.fSubset) {
|
||||
// Subsets are not supported.
|
||||
@ -256,20 +248,17 @@ SkCodec::Result SkBmpRLECodec::onPrepareToDecode(const SkImageInfo& dstInfo,
|
||||
SkColorType colorTableColorType = dstInfo.colorType();
|
||||
if (this->colorXform()) {
|
||||
// Just set a known colorType for the colorTable. No need to actually transform
|
||||
// the colors in the colorTable since we do not allow decoding RLE to kIndex8.
|
||||
// the colors in the colorTable.
|
||||
colorTableColorType = kBGRA_8888_SkColorType;
|
||||
}
|
||||
|
||||
// Create the color table if necessary and prepare the stream for decode
|
||||
// Note that if it is non-NULL, inputColorCount will be modified
|
||||
if (!this->createColorTable(colorTableColorType, inputColorCount)) {
|
||||
if (!this->createColorTable(colorTableColorType)) {
|
||||
SkCodecPrintf("Error: could not create color table.\n");
|
||||
return SkCodec::kInvalidInput;
|
||||
}
|
||||
|
||||
// Copy the color table to the client if necessary
|
||||
copy_color_table(dstInfo, fColorTable.get(), inputColorPtr, inputColorCount);
|
||||
|
||||
// Initialize a buffer for encoded RLE data
|
||||
if (!this->initializeStreamBuffer()) {
|
||||
SkCodecPrintf("Error: cannot initialize stream buffer.\n");
|
||||
|
@ -44,12 +44,11 @@ public:
|
||||
protected:
|
||||
|
||||
Result onGetPixels(const SkImageInfo& dstInfo, void* dst,
|
||||
size_t dstRowBytes, const Options&, SkPMColor*,
|
||||
int*, int*) override;
|
||||
size_t dstRowBytes, const Options&,
|
||||
int*) override;
|
||||
|
||||
SkCodec::Result onPrepareToDecode(const SkImageInfo& dstInfo,
|
||||
const SkCodec::Options& options, SkPMColor inputColorPtr[],
|
||||
int* inputColorCount) override;
|
||||
const SkCodec::Options& options) override;
|
||||
|
||||
private:
|
||||
|
||||
@ -57,7 +56,7 @@ private:
|
||||
* Creates the color table
|
||||
* Sets colorCount to the new color count if it is non-nullptr
|
||||
*/
|
||||
bool createColorTable(SkColorType dstColorType, int* colorCount);
|
||||
bool createColorTable(SkColorType dstColorType);
|
||||
|
||||
bool initializeStreamBuffer();
|
||||
|
||||
|
@ -36,8 +36,6 @@ SkBmpStandardCodec::SkBmpStandardCodec(int width, int height, const SkEncodedInf
|
||||
SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo,
|
||||
void* dst, size_t dstRowBytes,
|
||||
const Options& opts,
|
||||
SkPMColor* inputColorPtr,
|
||||
int* inputColorCount,
|
||||
int* rowsDecoded) {
|
||||
if (opts.fSubset) {
|
||||
// Subsets are not supported.
|
||||
@ -48,7 +46,7 @@ SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo,
|
||||
return kInvalidScale;
|
||||
}
|
||||
|
||||
Result result = this->prepareToDecode(dstInfo, opts, inputColorPtr, inputColorCount);
|
||||
Result result = this->prepareToDecode(dstInfo, opts);
|
||||
if (kSuccess != result) {
|
||||
return result;
|
||||
}
|
||||
@ -63,20 +61,13 @@ SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo,
|
||||
/*
|
||||
* Process the color table for the bmp input
|
||||
*/
|
||||
bool SkBmpStandardCodec::createColorTable(SkColorType dstColorType, SkAlphaType dstAlphaType,
|
||||
int* numColors) {
|
||||
bool SkBmpStandardCodec::createColorTable(SkColorType dstColorType, SkAlphaType dstAlphaType) {
|
||||
// Allocate memory for color table
|
||||
uint32_t colorBytes = 0;
|
||||
SkPMColor colorTable[256];
|
||||
if (this->bitsPerPixel() <= 8) {
|
||||
// Inform the caller of the number of colors
|
||||
uint32_t maxColors = 1 << this->bitsPerPixel();
|
||||
if (nullptr != numColors) {
|
||||
// We set the number of colors to maxColors in order to ensure
|
||||
// safe memory accesses. Otherwise, an invalid pixel could
|
||||
// access memory outside of our color table array.
|
||||
*numColors = maxColors;
|
||||
}
|
||||
// Don't bother reading more than maxColors.
|
||||
const uint32_t numColorsToRead =
|
||||
fNumColors == 0 ? maxColors : SkTMin(fNumColors, maxColors);
|
||||
@ -191,21 +182,18 @@ void SkBmpStandardCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Op
|
||||
}
|
||||
|
||||
SkCodec::Result SkBmpStandardCodec::onPrepareToDecode(const SkImageInfo& dstInfo,
|
||||
const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
|
||||
const SkCodec::Options& options) {
|
||||
if (this->xformOnDecode()) {
|
||||
this->resetXformBuffer(dstInfo.width());
|
||||
}
|
||||
|
||||
// Create the color table if necessary and prepare the stream for decode
|
||||
// Note that if it is non-NULL, inputColorCount will be modified
|
||||
if (!this->createColorTable(dstInfo.colorType(), dstInfo.alphaType(), inputColorCount)) {
|
||||
if (!this->createColorTable(dstInfo.colorType(), dstInfo.alphaType())) {
|
||||
SkCodecPrintf("Error: could not create color table.\n");
|
||||
return SkCodec::kInvalidInput;
|
||||
}
|
||||
|
||||
// Copy the color table to the client if necessary
|
||||
copy_color_table(dstInfo, fColorTable.get(), inputColorPtr, inputColorCount);
|
||||
|
||||
// Initialize a swizzler
|
||||
this->initializeSwizzler(dstInfo, options);
|
||||
return SkCodec::kSuccess;
|
||||
@ -291,9 +279,8 @@ int SkBmpStandardCodec::decodeRows(const SkImageInfo& dstInfo, void* dst, size_t
|
||||
|
||||
void SkBmpStandardCodec::decodeIcoMask(SkStream* stream, const SkImageInfo& dstInfo,
|
||||
void* dst, size_t dstRowBytes) {
|
||||
// BMP in ICO have transparency, so this cannot be 565, and this mask
|
||||
// prevents us from using kIndex8. The below code depends on the output
|
||||
// being an SkPMColor.
|
||||
// BMP in ICO have transparency, so this cannot be 565. The below code depends
|
||||
// on the output being an SkPMColor.
|
||||
SkASSERT(kRGBA_8888_SkColorType == dstInfo.colorType() ||
|
||||
kBGRA_8888_SkColorType == dstInfo.colorType() ||
|
||||
kRGBA_F16_SkColorType == dstInfo.colorType());
|
||||
|
@ -47,16 +47,15 @@ public:
|
||||
protected:
|
||||
|
||||
Result onGetPixels(const SkImageInfo& dstInfo, void* dst,
|
||||
size_t dstRowBytes, const Options&, SkPMColor*,
|
||||
int*, int*) override;
|
||||
size_t dstRowBytes, const Options&,
|
||||
int*) override;
|
||||
|
||||
bool onInIco() const override {
|
||||
return fInIco;
|
||||
}
|
||||
|
||||
SkCodec::Result onPrepareToDecode(const SkImageInfo& dstInfo,
|
||||
const SkCodec::Options& options, SkPMColor inputColorPtr[],
|
||||
int* inputColorCount) override;
|
||||
const SkCodec::Options& options) override;
|
||||
|
||||
|
||||
uint64_t onGetFillValue(const SkImageInfo&) const override;
|
||||
@ -70,9 +69,8 @@ private:
|
||||
|
||||
/*
|
||||
* Creates the color table
|
||||
* Sets colorCount to the new color count if it is non-nullptr
|
||||
*/
|
||||
bool createColorTable(SkColorType colorType, SkAlphaType alphaType, int* colorCount);
|
||||
bool createColorTable(SkColorType colorType, SkAlphaType alphaType);
|
||||
|
||||
void initializeSwizzler(const SkImageInfo& dstInfo, const Options& opts);
|
||||
|
||||
|
@ -167,19 +167,6 @@ bool SkCodec::rewindIfNeeded() {
|
||||
return this->onRewind();
|
||||
}
|
||||
|
||||
#define CHECK_COLOR_TABLE \
|
||||
if (kIndex_8_SkColorType == info.colorType()) { \
|
||||
if (nullptr == ctable || nullptr == ctableCount) { \
|
||||
return SkCodec::kInvalidParameters; \
|
||||
} \
|
||||
} else { \
|
||||
if (ctableCount) { \
|
||||
*ctableCount = 0; \
|
||||
} \
|
||||
ctableCount = nullptr; \
|
||||
ctable = nullptr; \
|
||||
}
|
||||
|
||||
static void zero_rect(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes,
|
||||
SkIRect frameRect) {
|
||||
if (!frameRect.intersect(dstInfo.bounds())) {
|
||||
@ -205,11 +192,6 @@ SkCodec::Result SkCodec::handleFrameIndex(const SkImageInfo& info, void* pixels,
|
||||
return kInvalidParameters;
|
||||
}
|
||||
|
||||
// index 8 is not supported beyond the first frame.
|
||||
if (index < 0 || info.colorType() == kIndex_8_SkColorType) {
|
||||
return kInvalidParameters;
|
||||
}
|
||||
|
||||
if (index >= this->onGetFrameCount()) {
|
||||
return kIncompleteInput;
|
||||
}
|
||||
@ -252,8 +234,7 @@ SkCodec::Result SkCodec::handleFrameIndex(const SkImageInfo& info, void* pixels,
|
||||
Options prevFrameOptions(options);
|
||||
prevFrameOptions.fFrameIndex = requiredFrame;
|
||||
prevFrameOptions.fZeroInitialized = kNo_ZeroInitialized;
|
||||
const Result result = this->getPixels(info, pixels, rowBytes, &prevFrameOptions,
|
||||
nullptr, nullptr);
|
||||
const Result result = this->getPixels(info, pixels, rowBytes, &prevFrameOptions);
|
||||
if (result == kSuccess) {
|
||||
const auto* prevFrame = frameHolder->getFrame(requiredFrame);
|
||||
const auto disposalMethod = prevFrame->getDisposalMethod();
|
||||
@ -266,7 +247,7 @@ SkCodec::Result SkCodec::handleFrameIndex(const SkImageInfo& info, void* pixels,
|
||||
}
|
||||
|
||||
SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
|
||||
const Options* options, SkPMColor ctable[], int* ctableCount) {
|
||||
const Options* options) {
|
||||
if (kUnknown_SkColorType == info.colorType()) {
|
||||
return kInvalidConversion;
|
||||
}
|
||||
@ -277,8 +258,6 @@ SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t
|
||||
return kInvalidParameters;
|
||||
}
|
||||
|
||||
CHECK_COLOR_TABLE;
|
||||
|
||||
if (!this->rewindIfNeeded()) {
|
||||
return kCouldNotRewind;
|
||||
}
|
||||
@ -314,14 +293,7 @@ SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t
|
||||
// On an incomplete decode, the subclass will specify the number of scanlines that it decoded
|
||||
// successfully.
|
||||
int rowsDecoded = 0;
|
||||
const Result result = this->onGetPixels(info, pixels, rowBytes, *options, ctable, ctableCount,
|
||||
&rowsDecoded);
|
||||
|
||||
if (ctableCount) {
|
||||
if (kIncompleteInput == result || kSuccess == result || kErrorInInput == result) {
|
||||
SkASSERT(*ctableCount >= 0 && *ctableCount <= 256);
|
||||
}
|
||||
}
|
||||
const Result result = this->onGetPixels(info, pixels, rowBytes, *options, &rowsDecoded);
|
||||
|
||||
// A return value of kIncompleteInput indicates a truncated image stream.
|
||||
// In this case, we will fill any uninitialized memory with a default value.
|
||||
@ -342,12 +314,8 @@ SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t
|
||||
return result;
|
||||
}
|
||||
|
||||
SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
|
||||
return this->getPixels(info, pixels, rowBytes, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
SkCodec::Result SkCodec::startIncrementalDecode(const SkImageInfo& info, void* pixels,
|
||||
size_t rowBytes, const SkCodec::Options* options, SkPMColor* ctable, int* ctableCount) {
|
||||
size_t rowBytes, const SkCodec::Options* options) {
|
||||
fStartedIncrementalDecode = false;
|
||||
|
||||
if (kUnknown_SkColorType == info.colorType()) {
|
||||
@ -357,9 +325,6 @@ SkCodec::Result SkCodec::startIncrementalDecode(const SkImageInfo& info, void* p
|
||||
return kInvalidParameters;
|
||||
}
|
||||
|
||||
// Ensure that valid color ptrs are passed in for kIndex8 color type
|
||||
CHECK_COLOR_TABLE;
|
||||
|
||||
// FIXME: If the rows come after the rows of a previous incremental decode,
|
||||
// we might be able to skip the rewind, but only the implementation knows
|
||||
// that. (e.g. PNG will always need to rewind, since we called longjmp, but
|
||||
@ -399,8 +364,7 @@ SkCodec::Result SkCodec::startIncrementalDecode(const SkImageInfo& info, void* p
|
||||
fDstInfo = info;
|
||||
fOptions = *options;
|
||||
|
||||
const Result result = this->onStartIncrementalDecode(info, pixels, rowBytes,
|
||||
fOptions, ctable, ctableCount);
|
||||
const Result result = this->onStartIncrementalDecode(info, pixels, rowBytes, fOptions);
|
||||
if (kSuccess == result) {
|
||||
fStartedIncrementalDecode = true;
|
||||
} else if (kUnimplemented == result) {
|
||||
@ -418,11 +382,9 @@ SkCodec::Result SkCodec::startIncrementalDecode(const SkImageInfo& info, void* p
|
||||
|
||||
|
||||
SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& info,
|
||||
const SkCodec::Options* options, SkPMColor ctable[], int* ctableCount) {
|
||||
const SkCodec::Options* options) {
|
||||
// Reset fCurrScanline in case of failure.
|
||||
fCurrScanline = -1;
|
||||
// Ensure that valid color ptrs are passed in for kIndex8 color type
|
||||
CHECK_COLOR_TABLE;
|
||||
|
||||
if (!this->rewindIfNeeded()) {
|
||||
return kCouldNotRewind;
|
||||
@ -450,7 +412,7 @@ SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& info,
|
||||
return kInvalidScale;
|
||||
}
|
||||
|
||||
const Result result = this->onStartScanlineDecode(info, *options, ctable, ctableCount);
|
||||
const Result result = this->onStartScanlineDecode(info, *options);
|
||||
if (result != SkCodec::kSuccess) {
|
||||
return result;
|
||||
}
|
||||
@ -461,12 +423,6 @@ SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& info,
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
#undef CHECK_COLOR_TABLE
|
||||
|
||||
SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& info) {
|
||||
return this->startScanlineDecode(info, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
int SkCodec::getScanlines(void* dst, int countLines, size_t rowBytes) {
|
||||
if (fCurrScanline < 0) {
|
||||
return 0;
|
||||
@ -530,7 +486,7 @@ uint64_t SkCodec::onGetFillValue(const SkImageInfo& dstInfo) const {
|
||||
return (kOpaque_SkAlphaType == fSrcInfo.alphaType()) ? opaqueColor : transparentColor;
|
||||
}
|
||||
default: {
|
||||
// This not only handles the kN32 case, but also k565, kGray8, kIndex8, since
|
||||
// This not only handles the kN32 case, but also k565, kGray8, since
|
||||
// the low bits are zeros.
|
||||
return (kOpaque_SkAlphaType == fSrcInfo.alphaType()) ?
|
||||
SK_ColorBLACK : SK_ColorTRANSPARENT;
|
||||
@ -583,7 +539,6 @@ static inline SkColorSpaceXform::ColorFormat select_xform_format_ct(SkColorType
|
||||
case kBGRA_8888_SkColorType:
|
||||
return SkColorSpaceXform::kBGRA_8888_ColorFormat;
|
||||
case kRGB_565_SkColorType:
|
||||
case kIndex_8_SkColorType:
|
||||
#ifdef SK_PMCOLOR_IS_RGBA
|
||||
return SkColorSpaceXform::kRGBA_8888_ColorFormat;
|
||||
#else
|
||||
|
@ -44,8 +44,7 @@ bool SkCodecImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, s
|
||||
const Options& opts) {
|
||||
SkCodec::Options codecOpts;
|
||||
codecOpts.fPremulBehavior = opts.fBehavior;
|
||||
SkCodec::Result result = fCodec->getPixels(info, pixels, rowBytes, &codecOpts, nullptr,
|
||||
nullptr);
|
||||
SkCodec::Result result = fCodec->getPixels(info, pixels, rowBytes, &codecOpts);
|
||||
switch (result) {
|
||||
case SkCodec::kSuccess:
|
||||
case SkCodec::kIncompleteInput:
|
||||
|
@ -128,8 +128,6 @@ static inline uint64_t get_color_table_fill_value(SkColorType dstColorType, SkAl
|
||||
return colorPtr[fillIndex];
|
||||
case kRGB_565_SkColorType:
|
||||
return SkPixel32ToPixel16(colorPtr[fillIndex]);
|
||||
case kIndex_8_SkColorType:
|
||||
return fillIndex;
|
||||
case kRGBA_F16_SkColorType: {
|
||||
SkASSERT(colorXform);
|
||||
uint64_t dstColor;
|
||||
@ -147,20 +145,6 @@ static inline uint64_t get_color_table_fill_value(SkColorType dstColorType, SkAl
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Copy the codec color table back to the client when kIndex8 color type is requested
|
||||
*/
|
||||
static inline void copy_color_table(const SkImageInfo& dstInfo, SkColorTable* colorTable,
|
||||
SkPMColor* inputColorPtr, int* inputColorCount) {
|
||||
if (kIndex_8_SkColorType == dstInfo.colorType()) {
|
||||
SkASSERT(nullptr != inputColorPtr);
|
||||
SkASSERT(nullptr != inputColorCount);
|
||||
SkASSERT(nullptr != colorTable);
|
||||
memcpy(inputColorPtr, colorTable->readColors(), *inputColorCount * sizeof(SkPMColor));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute row bytes for an image using pixels per byte
|
||||
*/
|
||||
@ -331,7 +315,6 @@ static inline SkAlphaType select_xform_alpha(SkAlphaType dstAlphaType, SkAlphaTy
|
||||
* Color Type Conversions
|
||||
* - Always support kRGBA_8888, kBGRA_8888
|
||||
* - Support kRGBA_F16 when there is a linear dst color space
|
||||
* - Support kIndex8 if it matches the src
|
||||
* - Support k565 if kOpaque and color correction is not required
|
||||
* - Support k565 if it matches the src, kOpaque, and color correction is not required
|
||||
*/
|
||||
@ -348,8 +331,6 @@ static inline bool conversion_possible(const SkImageInfo& dst, const SkImageInfo
|
||||
return true;
|
||||
case kRGBA_F16_SkColorType:
|
||||
return dst.colorSpace() && dst.colorSpace()->gammaIsLinear();
|
||||
case kIndex_8_SkColorType:
|
||||
return kIndex_8_SkColorType == src.colorType();
|
||||
case kRGB_565_SkColorType:
|
||||
return kOpaque_SkAlphaType == src.alphaType();
|
||||
case kGray_8_SkColorType:
|
||||
|
@ -94,10 +94,6 @@ SkCodec* SkGifCodec::NewFromStream(SkStream* stream) {
|
||||
// expanding to 8 bits and take advantage of the SkSwizzler to work from 4.
|
||||
const auto encodedInfo = SkEncodedInfo::Make(SkEncodedInfo::kPalette_Color, alpha, 8);
|
||||
|
||||
// Although the encodedInfo is always kPalette_Color, it is possible that kIndex_8 is
|
||||
// unsupported if the frame is subset and there is no transparent pixel.
|
||||
const auto colorType = reader->firstFrameSupportsIndex8() ? kIndex_8_SkColorType
|
||||
: kN32_SkColorType;
|
||||
// The choice of unpremul versus premul is arbitrary, since all colors are either fully
|
||||
// opaque or fully transparent (i.e. kBinary), but we stored the transparent colors as all
|
||||
// zeroes, which is arguably premultiplied.
|
||||
@ -105,7 +101,7 @@ SkCodec* SkGifCodec::NewFromStream(SkStream* stream) {
|
||||
: kOpaque_SkAlphaType;
|
||||
|
||||
const auto imageInfo = SkImageInfo::Make(reader->screenWidth(), reader->screenHeight(),
|
||||
colorType, alphaType,
|
||||
kN32_SkColorType, alphaType,
|
||||
SkColorSpace::MakeSRGB());
|
||||
return new SkGifCodec(encodedInfo, imageInfo, reader.release());
|
||||
}
|
||||
@ -189,8 +185,7 @@ void SkGifCodec::initializeColorTable(const SkImageInfo& dstInfo, int frameIndex
|
||||
}
|
||||
|
||||
|
||||
SkCodec::Result SkGifCodec::prepareToDecode(const SkImageInfo& dstInfo, SkPMColor* inputColorPtr,
|
||||
int* inputColorCount, const Options& opts) {
|
||||
SkCodec::Result SkGifCodec::prepareToDecode(const SkImageInfo& dstInfo, const Options& opts) {
|
||||
if (opts.fSubset) {
|
||||
return gif_error("Subsets not supported.\n", kUnimplemented);
|
||||
}
|
||||
@ -251,11 +246,6 @@ SkCodec::Result SkGifCodec::prepareToDecode(const SkImageInfo& dstInfo, SkPMColo
|
||||
this->initializeSwizzler(dstInfo, frameIndex);
|
||||
|
||||
SkASSERT(fCurrColorTable);
|
||||
if (inputColorCount) {
|
||||
*inputColorCount = fCurrColorTable->count();
|
||||
}
|
||||
copy_color_table(dstInfo, fCurrColorTable.get(), inputColorPtr, inputColorCount);
|
||||
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
@ -297,10 +287,8 @@ void SkGifCodec::initializeSwizzler(const SkImageInfo& dstInfo, int frameIndex)
|
||||
SkCodec::Result SkGifCodec::onGetPixels(const SkImageInfo& dstInfo,
|
||||
void* pixels, size_t dstRowBytes,
|
||||
const Options& opts,
|
||||
SkPMColor* inputColorPtr,
|
||||
int* inputColorCount,
|
||||
int* rowsDecoded) {
|
||||
Result result = this->prepareToDecode(dstInfo, inputColorPtr, inputColorCount, opts);
|
||||
Result result = this->prepareToDecode(dstInfo, opts);
|
||||
switch (result) {
|
||||
case kSuccess:
|
||||
break;
|
||||
@ -328,10 +316,8 @@ SkCodec::Result SkGifCodec::onGetPixels(const SkImageInfo& dstInfo,
|
||||
|
||||
SkCodec::Result SkGifCodec::onStartIncrementalDecode(const SkImageInfo& dstInfo,
|
||||
void* pixels, size_t dstRowBytes,
|
||||
const SkCodec::Options& opts,
|
||||
SkPMColor* inputColorPtr,
|
||||
int* inputColorCount) {
|
||||
Result result = this->prepareToDecode(dstInfo, inputColorPtr, inputColorCount, opts);
|
||||
const SkCodec::Options& opts) {
|
||||
Result result = this->prepareToDecode(dstInfo, opts);
|
||||
if (result != kSuccess) {
|
||||
return result;
|
||||
}
|
||||
@ -423,28 +409,8 @@ SkCodec::Result SkGifCodec::decodeFrame(bool firstAttempt, const Options& opts,
|
||||
}
|
||||
|
||||
uint64_t SkGifCodec::onGetFillValue(const SkImageInfo& dstInfo) const {
|
||||
// Note: Using fCurrColorTable relies on having called initializeColorTable already.
|
||||
// This is (currently) safe because this method is only called when filling, after
|
||||
// initializeColorTable has been called.
|
||||
// FIXME: Is there a way to make this less fragile?
|
||||
if (dstInfo.colorType() == kIndex_8_SkColorType && fCurrColorTableIsReal) {
|
||||
// We only support index 8 for the first frame, for backwards
|
||||
// compatibity on Android, so we are using the color table for the first frame.
|
||||
SkASSERT(this->options().fFrameIndex == 0);
|
||||
// Use the transparent index for the first frame.
|
||||
const int transPixel = fReader->frameContext(0)->transparentPixel();
|
||||
if (transPixel >= 0 && transPixel < fCurrColorTable->count()) {
|
||||
return transPixel;
|
||||
}
|
||||
// Fall through to return SK_ColorTRANSPARENT (i.e. 0). This choice is arbitrary,
|
||||
// but we have to pick something inside the color table, and this one is as good
|
||||
// as any.
|
||||
}
|
||||
// Using transparent as the fill value matches the behavior in Chromium,
|
||||
// which ignores the background color.
|
||||
// If the colorType is kIndex_8, and there was no color table (i.e.
|
||||
// fCurrColorTableIsReal is false), this value (zero) corresponds to the
|
||||
// only entry in the dummy color table provided to the client.
|
||||
return SK_ColorTRANSPARENT;
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ protected:
|
||||
* Performs the full gif decode
|
||||
*/
|
||||
Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&,
|
||||
SkPMColor*, int*, int*) override;
|
||||
int*) override;
|
||||
|
||||
SkEncodedImageFormat onGetEncodedFormat() const override {
|
||||
return SkEncodedImageFormat::kGIF;
|
||||
@ -55,7 +55,7 @@ protected:
|
||||
int onGetRepetitionCount() override;
|
||||
|
||||
Result onStartIncrementalDecode(const SkImageInfo& /*dstInfo*/, void*, size_t,
|
||||
const SkCodec::Options&, SkPMColor*, int*) override;
|
||||
const SkCodec::Options&) override;
|
||||
|
||||
Result onIncrementalDecode(int*) override;
|
||||
|
||||
@ -74,11 +74,9 @@ private:
|
||||
void initializeColorTable(const SkImageInfo& dstInfo, int frameIndex);
|
||||
|
||||
/*
|
||||
* Does necessary setup, including setting up the color table and swizzler,
|
||||
* and reports color info to the client.
|
||||
* Does necessary setup, including setting up the color table and swizzler.
|
||||
*/
|
||||
Result prepareToDecode(const SkImageInfo& dstInfo, SkPMColor* inputColorPtr,
|
||||
int* inputColorCount, const Options& opts);
|
||||
Result prepareToDecode(const SkImageInfo& dstInfo, const Options& opts);
|
||||
|
||||
/*
|
||||
* Initializes the swizzler.
|
||||
|
@ -255,8 +255,8 @@ bool SkIcoCodec::onDimensionsSupported(const SkISize& dim) {
|
||||
*/
|
||||
SkCodec::Result SkIcoCodec::onGetPixels(const SkImageInfo& dstInfo,
|
||||
void* dst, size_t dstRowBytes,
|
||||
const Options& opts, SkPMColor* colorTable,
|
||||
int* colorCount, int* rowsDecoded) {
|
||||
const Options& opts,
|
||||
int* rowsDecoded) {
|
||||
if (opts.fSubset) {
|
||||
// Subsets are not supported.
|
||||
return kUnimplemented;
|
||||
@ -271,7 +271,7 @@ SkCodec::Result SkIcoCodec::onGetPixels(const SkImageInfo& dstInfo,
|
||||
}
|
||||
|
||||
SkCodec* embeddedCodec = fEmbeddedCodecs->operator[](index).get();
|
||||
result = embeddedCodec->getPixels(dstInfo, dst, dstRowBytes, &opts, colorTable, colorCount);
|
||||
result = embeddedCodec->getPixels(dstInfo, dst, dstRowBytes, &opts);
|
||||
switch (result) {
|
||||
case kSuccess:
|
||||
case kIncompleteInput:
|
||||
@ -292,7 +292,7 @@ SkCodec::Result SkIcoCodec::onGetPixels(const SkImageInfo& dstInfo,
|
||||
}
|
||||
|
||||
SkCodec::Result SkIcoCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
|
||||
const SkCodec::Options& options, SkPMColor colorTable[], int* colorCount) {
|
||||
const SkCodec::Options& options) {
|
||||
int index = 0;
|
||||
SkCodec::Result result = kInvalidScale;
|
||||
while (true) {
|
||||
@ -302,7 +302,7 @@ SkCodec::Result SkIcoCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
|
||||
}
|
||||
|
||||
SkCodec* embeddedCodec = fEmbeddedCodecs->operator[](index).get();
|
||||
result = embeddedCodec->startScanlineDecode(dstInfo, &options, colorTable, colorCount);
|
||||
result = embeddedCodec->startScanlineDecode(dstInfo, &options);
|
||||
if (kSuccess == result) {
|
||||
fCurrScanlineCodec = embeddedCodec;
|
||||
fCurrIncrementalCodec = nullptr;
|
||||
@ -327,8 +327,7 @@ bool SkIcoCodec::onSkipScanlines(int count) {
|
||||
}
|
||||
|
||||
SkCodec::Result SkIcoCodec::onStartIncrementalDecode(const SkImageInfo& dstInfo,
|
||||
void* pixels, size_t rowBytes, const SkCodec::Options& options,
|
||||
SkPMColor* colorTable, int* colorCount) {
|
||||
void* pixels, size_t rowBytes, const SkCodec::Options& options) {
|
||||
int index = 0;
|
||||
while (true) {
|
||||
index = this->chooseCodec(dstInfo.dimensions(), index);
|
||||
@ -338,7 +337,7 @@ SkCodec::Result SkIcoCodec::onStartIncrementalDecode(const SkImageInfo& dstInfo,
|
||||
|
||||
SkCodec* embeddedCodec = fEmbeddedCodecs->operator[](index).get();
|
||||
switch (embeddedCodec->startIncrementalDecode(dstInfo,
|
||||
pixels, rowBytes, &options, colorTable, colorCount)) {
|
||||
pixels, rowBytes, &options)) {
|
||||
case kSuccess:
|
||||
fCurrIncrementalCodec = embeddedCodec;
|
||||
fCurrScanlineCodec = nullptr;
|
||||
@ -356,8 +355,7 @@ SkCodec::Result SkIcoCodec::onStartIncrementalDecode(const SkImageInfo& dstInfo,
|
||||
// valid for scanline decoding.
|
||||
// Once BMP supports incremental decoding this workaround can go
|
||||
// away.
|
||||
if (embeddedCodec->startScanlineDecode(dstInfo, nullptr,
|
||||
colorTable, colorCount) == kSuccess) {
|
||||
if (embeddedCodec->startScanlineDecode(dstInfo) == kSuccess) {
|
||||
return kUnimplemented;
|
||||
}
|
||||
// Move on to the next embedded codec.
|
||||
|
@ -40,7 +40,7 @@ protected:
|
||||
* Initiates the Ico decode
|
||||
*/
|
||||
Result onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options&,
|
||||
SkPMColor*, int*, int*) override;
|
||||
int*) override;
|
||||
|
||||
SkEncodedImageFormat onGetEncodedFormat() const override {
|
||||
return SkEncodedImageFormat::kICO;
|
||||
@ -50,15 +50,15 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
Result onStartScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options& options,
|
||||
SkPMColor inputColorPtr[], int* inputColorCount) override;
|
||||
Result onStartScanlineDecode(const SkImageInfo& dstInfo,
|
||||
const SkCodec::Options& options) override;
|
||||
|
||||
int onGetScanlines(void* dst, int count, size_t rowBytes) override;
|
||||
|
||||
bool onSkipScanlines(int count) override;
|
||||
|
||||
Result onStartIncrementalDecode(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes,
|
||||
const SkCodec::Options&, SkPMColor*, int*) override;
|
||||
const SkCodec::Options&) override;
|
||||
|
||||
Result onIncrementalDecode(int* rowsDecoded) override;
|
||||
|
||||
|
@ -556,7 +556,7 @@ static inline bool needs_swizzler_to_convert_from_cmyk(J_COLOR_SPACE jpegColorTy
|
||||
*/
|
||||
SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo,
|
||||
void* dst, size_t dstRowBytes,
|
||||
const Options& options, SkPMColor*, int*,
|
||||
const Options& options,
|
||||
int* rowsDecoded) {
|
||||
if (options.fSubset) {
|
||||
// Subsets are not supported.
|
||||
@ -673,7 +673,7 @@ SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) {
|
||||
}
|
||||
|
||||
SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
|
||||
const Options& options, SkPMColor ctable[], int* ctableCount) {
|
||||
const Options& options) {
|
||||
// Set the jump location for libjpeg errors
|
||||
if (setjmp(fDecoderMgr->getJmpBuf())) {
|
||||
SkCodecPrintf("setjmp: Error from libjpeg\n");
|
||||
|
@ -45,7 +45,7 @@ protected:
|
||||
* Initiates the jpeg decode
|
||||
*/
|
||||
Result onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options&,
|
||||
SkPMColor*, int*, int*) override;
|
||||
int*) override;
|
||||
|
||||
bool onQueryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const override;
|
||||
|
||||
@ -120,8 +120,8 @@ private:
|
||||
* Scanline decoding.
|
||||
*/
|
||||
SkSampler* getSampler(bool createIfNecessary) override;
|
||||
Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options,
|
||||
SkPMColor ctable[], int* ctableCount) override;
|
||||
Result onStartScanlineDecode(const SkImageInfo& dstInfo,
|
||||
const Options& options) override;
|
||||
int onGetScanlines(void* dst, int count, size_t rowBytes) override;
|
||||
bool onSkipScanlines(int count) override;
|
||||
|
||||
|
@ -245,7 +245,7 @@ void SkPngCodec::processData() {
|
||||
static const SkColorType kXformSrcColorType = kRGBA_8888_SkColorType;
|
||||
|
||||
// Note: SkColorTable claims to store SkPMColors, which is not necessarily the case here.
|
||||
bool SkPngCodec::createColorTable(const SkImageInfo& dstInfo, int* ctableCount) {
|
||||
bool SkPngCodec::createColorTable(const SkImageInfo& dstInfo) {
|
||||
|
||||
int numColors;
|
||||
png_color* palette;
|
||||
@ -308,11 +308,6 @@ bool SkPngCodec::createColorTable(const SkImageInfo& dstInfo, int* ctableCount)
|
||||
sk_memset32(colorTable + numColors, lastColor, maxColors - numColors);
|
||||
}
|
||||
|
||||
// Set the new color count.
|
||||
if (ctableCount != nullptr) {
|
||||
*ctableCount = maxColors;
|
||||
}
|
||||
|
||||
fColorTable.reset(new SkColorTable(colorTable, maxColors));
|
||||
return true;
|
||||
}
|
||||
@ -973,8 +968,7 @@ void SkPngCodec::destroyReadStruct() {
|
||||
// Getting the pixels
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkCodec::Result SkPngCodec::initializeXforms(const SkImageInfo& dstInfo, const Options& options,
|
||||
SkPMColor ctable[], int* ctableCount) {
|
||||
SkCodec::Result SkPngCodec::initializeXforms(const SkImageInfo& dstInfo, const Options& options) {
|
||||
if (setjmp(PNG_JMPBUF((png_struct*)fPng_ptr))) {
|
||||
SkCodecPrintf("Failed on png_read_update_info.\n");
|
||||
return kInvalidInput;
|
||||
@ -1011,14 +1005,11 @@ SkCodec::Result SkPngCodec::initializeXforms(const SkImageInfo& dstInfo, const O
|
||||
}
|
||||
|
||||
if (SkEncodedInfo::kPalette_Color == this->getEncodedInfo().color()) {
|
||||
if (!this->createColorTable(dstInfo, ctableCount)) {
|
||||
if (!this->createColorTable(dstInfo)) {
|
||||
return kInvalidInput;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the color table to the client if they request kIndex8 mode.
|
||||
copy_color_table(dstInfo, fColorTable.get(), ctable, ctableCount);
|
||||
|
||||
this->initializeSwizzler(dstInfo, options, skipFormatConversion);
|
||||
return kSuccess;
|
||||
}
|
||||
@ -1092,13 +1083,12 @@ bool SkPngCodec::onRewind() {
|
||||
|
||||
SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
|
||||
size_t rowBytes, const Options& options,
|
||||
SkPMColor ctable[], int* ctableCount,
|
||||
int* rowsDecoded) {
|
||||
if (!conversion_possible(dstInfo, this->getInfo())) {
|
||||
return kInvalidConversion;
|
||||
}
|
||||
|
||||
Result result = this->initializeXforms(dstInfo, options, ctable, ctableCount);
|
||||
Result result = this->initializeXforms(dstInfo, options);
|
||||
if (kSuccess != result) {
|
||||
return result;
|
||||
}
|
||||
@ -1113,13 +1103,12 @@ SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
|
||||
}
|
||||
|
||||
SkCodec::Result SkPngCodec::onStartIncrementalDecode(const SkImageInfo& dstInfo,
|
||||
void* dst, size_t rowBytes, const SkCodec::Options& options,
|
||||
SkPMColor* ctable, int* ctableCount) {
|
||||
void* dst, size_t rowBytes, const SkCodec::Options& options) {
|
||||
if (!conversion_possible(dstInfo, this->getInfo())) {
|
||||
return kInvalidConversion;
|
||||
}
|
||||
|
||||
Result result = this->initializeXforms(dstInfo, options, ctable, ctableCount);
|
||||
Result result = this->initializeXforms(dstInfo, options);
|
||||
if (kSuccess != result) {
|
||||
return result;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ protected:
|
||||
SkPngCodec(const SkEncodedInfo&, const SkImageInfo&, SkStream*, SkPngChunkReader*,
|
||||
void* png_ptr, void* info_ptr, int bitDepth);
|
||||
|
||||
Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, SkPMColor*, int*, int*)
|
||||
Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, int*)
|
||||
override;
|
||||
SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kPNG; }
|
||||
bool onRewind() override;
|
||||
@ -73,8 +73,7 @@ protected:
|
||||
void processData();
|
||||
|
||||
Result onStartIncrementalDecode(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes,
|
||||
const SkCodec::Options&,
|
||||
SkPMColor* ctable, int* ctableCount) override;
|
||||
const SkCodec::Options&) override;
|
||||
Result onIncrementalDecode(int*) override;
|
||||
|
||||
sk_sp<SkPngChunkReader> fPngChunkReader;
|
||||
@ -101,10 +100,9 @@ private:
|
||||
kSwizzleColor_XformMode,
|
||||
};
|
||||
|
||||
bool createColorTable(const SkImageInfo& dstInfo, int* ctableCount);
|
||||
bool createColorTable(const SkImageInfo& dstInfo);
|
||||
// Helper to set up swizzler, color xforms, and color table. Also calls png_read_update_info.
|
||||
SkCodec::Result initializeXforms(const SkImageInfo& dstInfo, const Options&,
|
||||
SkPMColor* colorPtr, int* colorCount);
|
||||
SkCodec::Result initializeXforms(const SkImageInfo& dstInfo, const Options&);
|
||||
void initializeSwizzler(const SkImageInfo& dstInfo, const Options&, bool skipFormatConversion);
|
||||
void allocateStorage(const SkImageInfo& dstInfo);
|
||||
void destroyReadStruct();
|
||||
|
@ -24,7 +24,5 @@ SkCodec::Result SkRawAdapterCodec::onGetAndroidPixels(
|
||||
SkCodec::Options codecOptions;
|
||||
codecOptions.fZeroInitialized = options.fZeroInitialized;
|
||||
codecOptions.fSubset = options.fSubset;
|
||||
return this->codec()->getPixels(
|
||||
info, pixels, rowBytes, &codecOptions, options.fColorPtr,
|
||||
options.fColorCount);
|
||||
return this->codec()->getPixels(info, pixels, rowBytes, &codecOptions);
|
||||
}
|
||||
|
@ -688,7 +688,6 @@ SkCodec* SkRawCodec::NewFromStream(SkStream* stream) {
|
||||
|
||||
SkCodec::Result SkRawCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
|
||||
size_t dstRowBytes, const Options& options,
|
||||
SkPMColor ctable[], int* ctableCount,
|
||||
int* rowsDecoded) {
|
||||
if (!conversion_possible(dstInfo, this->getInfo()) ||
|
||||
!this->initializeColorXform(dstInfo, options.fPremulBehavior))
|
||||
|
@ -35,7 +35,7 @@ public:
|
||||
protected:
|
||||
|
||||
Result onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options&,
|
||||
SkPMColor*, int*, int*) override;
|
||||
int*) override;
|
||||
|
||||
SkEncodedImageFormat onGetEncodedFormat() const override {
|
||||
return SkEncodedImageFormat::kDNG;
|
||||
|
@ -80,8 +80,7 @@ SkCodec::Result SkSampledCodec::onGetAndroidPixels(const SkImageInfo& info, void
|
||||
SkIRect* subset = options.fSubset;
|
||||
if (!subset || subset->size() == this->codec()->getInfo().dimensions()) {
|
||||
if (this->codec()->dimensionsSupported(info.dimensions())) {
|
||||
return this->codec()->getPixels(info, pixels, rowBytes, &codecOptions,
|
||||
options.fColorPtr, options.fColorCount);
|
||||
return this->codec()->getPixels(info, pixels, rowBytes, &codecOptions);
|
||||
}
|
||||
|
||||
// If the native codec does not support the requested scale, scale by sampling.
|
||||
@ -112,8 +111,7 @@ SkCodec::Result SkSampledCodec::onGetAndroidPixels(const SkImageInfo& info, void
|
||||
scaledSubsetWidth, scaledSubsetHeight);
|
||||
codecOptions.fSubset = &incrementalSubset;
|
||||
const SkCodec::Result startResult = this->codec()->startIncrementalDecode(
|
||||
scaledInfo, pixels, rowBytes, &codecOptions,
|
||||
options.fColorPtr, options.fColorCount);
|
||||
scaledInfo, pixels, rowBytes, &codecOptions);
|
||||
if (SkCodec::kSuccess == startResult) {
|
||||
int rowsDecoded;
|
||||
const SkCodec::Result incResult = this->codec()->incrementalDecode(&rowsDecoded);
|
||||
@ -140,7 +138,7 @@ SkCodec::Result SkSampledCodec::onGetAndroidPixels(const SkImageInfo& info, void
|
||||
codecOptions.fSubset = &scanlineSubset;
|
||||
|
||||
SkCodec::Result result = this->codec()->startScanlineDecode(scaledInfo,
|
||||
&codecOptions, options.fColorPtr, options.fColorCount);
|
||||
&codecOptions);
|
||||
if (SkCodec::kSuccess != result) {
|
||||
return result;
|
||||
}
|
||||
@ -230,7 +228,7 @@ SkCodec::Result SkSampledCodec::sampledDecode(const SkImageInfo& info, void* pix
|
||||
incrementalOptions.fSubset = &incrementalSubset;
|
||||
}
|
||||
const SkCodec::Result startResult = this->codec()->startIncrementalDecode(nativeInfo,
|
||||
pixels, rowBytes, &incrementalOptions, options.fColorPtr, options.fColorCount);
|
||||
pixels, rowBytes, &incrementalOptions);
|
||||
if (SkCodec::kSuccess == startResult) {
|
||||
SkSampler* sampler = this->codec()->getSampler(true);
|
||||
if (!sampler) {
|
||||
@ -264,7 +262,7 @@ SkCodec::Result SkSampledCodec::sampledDecode(const SkImageInfo& info, void* pix
|
||||
|
||||
// Start the scanline decode.
|
||||
SkCodec::Result result = this->codec()->startScanlineDecode(nativeInfo,
|
||||
&sampledOptions, options.fColorPtr, options.fColorCount);
|
||||
&sampledOptions);
|
||||
if (SkCodec::kSuccess != result) {
|
||||
return result;
|
||||
}
|
||||
|
@ -21,15 +21,6 @@ static inline size_t get_src_row_bytes(int width) {
|
||||
return SkAlign8(width) >> 3;
|
||||
}
|
||||
|
||||
static inline void setup_color_table(SkColorType colorType,
|
||||
SkPMColor* colorPtr, int* colorCount) {
|
||||
if (kIndex_8_SkColorType == colorType) {
|
||||
colorPtr[0] = SK_ColorBLACK;
|
||||
colorPtr[1] = SK_ColorWHITE;
|
||||
*colorCount = 2;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool valid_color_type(const SkImageInfo& dstInfo) {
|
||||
switch (dstInfo.colorType()) {
|
||||
case kRGBA_8888_SkColorType:
|
||||
@ -97,9 +88,8 @@ bool SkWbmpCodec::onRewind() {
|
||||
return read_header(this->stream(), nullptr);
|
||||
}
|
||||
|
||||
SkSwizzler* SkWbmpCodec::initializeSwizzler(const SkImageInfo& info, const SkPMColor* ctable,
|
||||
const Options& opts) {
|
||||
return SkSwizzler::CreateSwizzler(this->getEncodedInfo(), ctable, info, opts);
|
||||
SkSwizzler* SkWbmpCodec::initializeSwizzler(const SkImageInfo& info, const Options& opts) {
|
||||
return SkSwizzler::CreateSwizzler(this->getEncodedInfo(), nullptr, info, opts);
|
||||
}
|
||||
|
||||
bool SkWbmpCodec::readRow(uint8_t* row) {
|
||||
@ -112,7 +102,6 @@ SkWbmpCodec::SkWbmpCodec(int width, int height, const SkEncodedInfo& info, SkStr
|
||||
stream, SkColorSpace::MakeSRGB())
|
||||
, fSrcRowBytes(get_src_row_bytes(this->getInfo().width()))
|
||||
, fSwizzler(nullptr)
|
||||
, fColorTable(nullptr)
|
||||
{}
|
||||
|
||||
SkEncodedImageFormat SkWbmpCodec::onGetEncodedFormat() const {
|
||||
@ -123,8 +112,6 @@ SkCodec::Result SkWbmpCodec::onGetPixels(const SkImageInfo& info,
|
||||
void* dst,
|
||||
size_t rowBytes,
|
||||
const Options& options,
|
||||
SkPMColor ctable[],
|
||||
int* ctableCount,
|
||||
int* rowsDecoded) {
|
||||
if (options.fSubset) {
|
||||
// Subsets are not supported.
|
||||
@ -135,11 +122,8 @@ SkCodec::Result SkWbmpCodec::onGetPixels(const SkImageInfo& info,
|
||||
return kInvalidConversion;
|
||||
}
|
||||
|
||||
// Prepare a color table if necessary
|
||||
setup_color_table(info.colorType(), ctable, ctableCount);
|
||||
|
||||
// Initialize the swizzler
|
||||
std::unique_ptr<SkSwizzler> swizzler(this->initializeSwizzler(info, ctable, options));
|
||||
std::unique_ptr<SkSwizzler> swizzler(this->initializeSwizzler(info, options));
|
||||
SkASSERT(swizzler);
|
||||
|
||||
// Perform the decode
|
||||
@ -191,7 +175,7 @@ bool SkWbmpCodec::onSkipScanlines(int count) {
|
||||
}
|
||||
|
||||
SkCodec::Result SkWbmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
|
||||
const Options& options, SkPMColor inputColorTable[], int* inputColorCount) {
|
||||
const Options& options) {
|
||||
if (options.fSubset) {
|
||||
// Subsets are not supported.
|
||||
return kUnimplemented;
|
||||
@ -203,16 +187,8 @@ SkCodec::Result SkWbmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
|
||||
return kInvalidConversion;
|
||||
}
|
||||
|
||||
// Fill in the color table
|
||||
setup_color_table(dstInfo.colorType(), inputColorTable, inputColorCount);
|
||||
|
||||
// Copy the color table to a pointer that can be owned by the scanline decoder
|
||||
if (kIndex_8_SkColorType == dstInfo.colorType()) {
|
||||
fColorTable.reset(new SkColorTable(inputColorTable, 2));
|
||||
}
|
||||
|
||||
// Initialize the swizzler
|
||||
fSwizzler.reset(this->initializeSwizzler(dstInfo, get_color_ptr(fColorTable.get()), options));
|
||||
fSwizzler.reset(this->initializeSwizzler(dstInfo, options));
|
||||
SkASSERT(fSwizzler);
|
||||
|
||||
fSrcBuffer.reset(fSrcRowBytes);
|
||||
|
@ -26,13 +26,13 @@ public:
|
||||
protected:
|
||||
SkEncodedImageFormat onGetEncodedFormat() const override;
|
||||
Result onGetPixels(const SkImageInfo&, void*, size_t,
|
||||
const Options&, SkPMColor[], int*, int*) override;
|
||||
const Options&, int*) override;
|
||||
bool onRewind() override;
|
||||
private:
|
||||
/*
|
||||
* Returns a swizzler on success, nullptr on failure
|
||||
*/
|
||||
SkSwizzler* initializeSwizzler(const SkImageInfo& info, const SkPMColor* ctable,
|
||||
SkSwizzler* initializeSwizzler(const SkImageInfo& info,
|
||||
const Options& opts);
|
||||
SkSampler* getSampler(bool createIfNecessary) override {
|
||||
SkASSERT(fSwizzler || !createIfNecessary);
|
||||
@ -50,13 +50,12 @@ private:
|
||||
|
||||
// Used for scanline decodes:
|
||||
std::unique_ptr<SkSwizzler> fSwizzler;
|
||||
sk_sp<SkColorTable> fColorTable;
|
||||
SkAutoTMalloc<uint8_t> fSrcBuffer;
|
||||
|
||||
int onGetScanlines(void* dst, int count, size_t dstRowBytes) override;
|
||||
bool onSkipScanlines(int count) override;
|
||||
Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options,
|
||||
SkPMColor inputColorTable[], int* inputColorCount) override;
|
||||
Result onStartScanlineDecode(const SkImageInfo& dstInfo,
|
||||
const Options& options) override;
|
||||
|
||||
typedef SkCodec INHERITED;
|
||||
};
|
||||
|
@ -41,6 +41,5 @@ SkCodec::Result SkWebpAdapterCodec::onGetAndroidPixels(const SkImageInfo& info,
|
||||
codecOptions.fZeroInitialized = options.fZeroInitialized;
|
||||
codecOptions.fSubset = options.fSubset;
|
||||
codecOptions.fPremulBehavior = SkTransferFunctionBehavior::kIgnore;
|
||||
return this->codec()->getPixels(info, pixels, rowBytes, &codecOptions, options.fColorPtr,
|
||||
options.fColorCount);
|
||||
return this->codec()->getPixels(info, pixels, rowBytes, &codecOptions);
|
||||
}
|
||||
|
@ -378,8 +378,7 @@ static void blend_line(SkColorType dstCT, void* dst,
|
||||
}
|
||||
|
||||
SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
|
||||
const Options& options, SkPMColor*, int*,
|
||||
int* rowsDecodedPtr) {
|
||||
const Options& options, int* rowsDecodedPtr) {
|
||||
const int index = options.fFrameIndex;
|
||||
SkASSERT(0 == index || index < fFrameHolder.size());
|
||||
|
||||
|
@ -31,8 +31,7 @@ public:
|
||||
static SkCodec* NewFromStream(SkStream*);
|
||||
static bool IsWebp(const void*, size_t);
|
||||
protected:
|
||||
Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, SkPMColor*, int*, int*)
|
||||
override;
|
||||
Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, int*) override;
|
||||
SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kWEBP; }
|
||||
|
||||
SkISize onGetScaledDimensions(float desiredScale) const override;
|
||||
|
@ -60,7 +60,7 @@ DEF_TEST(Codec_565, r) {
|
||||
options.fPriorFrame = SkCodec::kNone;
|
||||
|
||||
const auto result = codec->getPixels(info, bm.getPixels(), bm.rowBytes(),
|
||||
&options, nullptr, nullptr);
|
||||
&options);
|
||||
REPORTER_ASSERT(r, result == SkCodec::kSuccess);
|
||||
}
|
||||
|
||||
@ -329,7 +329,7 @@ DEF_TEST(Codec_frames, r) {
|
||||
opts.fFrameIndex = index;
|
||||
opts.fPriorFrame = cachedIndex;
|
||||
const auto result = codec->getPixels(decodeInfo, bm->getPixels(), bm->rowBytes(),
|
||||
&opts, nullptr, nullptr);
|
||||
&opts);
|
||||
if (cachedIndex != SkCodec::kNone && restore_previous(frameInfos[cachedIndex])) {
|
||||
if (result == SkCodec::kInvalidParameters) {
|
||||
return true;
|
||||
|
@ -209,7 +209,7 @@ DEF_TEST(Codec_partialAnim, r) {
|
||||
SkCodec::Options opts;
|
||||
opts.fFrameIndex = i;
|
||||
const SkCodec::Result result = fullCodec->getPixels(info, frame.getPixels(),
|
||||
frame.rowBytes(), &opts, nullptr, nullptr);
|
||||
frame.rowBytes(), &opts);
|
||||
|
||||
if (result == SkCodec::kIncompleteInput || result == SkCodec::kInvalidInput) {
|
||||
// We need to distinguish between a partial frame and no more frames.
|
||||
|
@ -17,21 +17,9 @@ inline bool decode_memory(const void* mem, size_t size, SkBitmap* bm) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Construct a color table for the decode if necessary
|
||||
sk_sp<SkColorTable> colorTable(nullptr);
|
||||
SkPMColor* colorPtr = nullptr;
|
||||
int* colorCountPtr = nullptr;
|
||||
int maxColors = 256;
|
||||
if (kIndex_8_SkColorType == codec->getInfo().colorType()) {
|
||||
SkPMColor colors[256];
|
||||
colorTable.reset(new SkColorTable(colors, maxColors));
|
||||
colorPtr = const_cast<SkPMColor*>(colorTable->readColors());
|
||||
colorCountPtr = &maxColors;
|
||||
}
|
||||
|
||||
bm->allocPixels(codec->getInfo(), colorTable);
|
||||
bm->allocPixels(codec->getInfo());
|
||||
const SkCodec::Result result = codec->getPixels(codec->getInfo(), bm->getPixels(),
|
||||
bm->rowBytes(), nullptr, colorPtr, colorCountPtr);
|
||||
bm->rowBytes());
|
||||
return result == SkCodec::kSuccess || result == SkCodec::kIncompleteInput;
|
||||
}
|
||||
#endif // CodecPriv_DEFINED
|
||||
|
@ -348,8 +348,7 @@ static void check(skiatest::Reporter* r,
|
||||
SkIRect subset = SkIRect::MakeXYWH(2 * (width / 3), 0, width / 3, height);
|
||||
options.fSubset = ⊂
|
||||
|
||||
const SkCodec::Result partialStartResult = codec->startScanlineDecode(info, &options,
|
||||
nullptr, nullptr);
|
||||
const auto partialStartResult = codec->startScanlineDecode(info, &options);
|
||||
REPORTER_ASSERT(r, partialStartResult == SkCodec::kSuccess);
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
@ -384,8 +383,7 @@ static void check(skiatest::Reporter* r,
|
||||
SkImageInfo subsetInfo = info.makeWH(subset.width(), subset.height());
|
||||
SkBitmap bm;
|
||||
bm.allocPixels(subsetInfo);
|
||||
const SkCodec::Result result = codec->getPixels(bm.info(), bm.getPixels(), bm.rowBytes(),
|
||||
&opts, nullptr, nullptr);
|
||||
const auto result = codec->getPixels(bm.info(), bm.getPixels(), bm.rowBytes(), &opts);
|
||||
|
||||
if (supportsSubsetDecoding) {
|
||||
if (expectedResult == SkCodec::kSuccess) {
|
||||
@ -668,53 +666,6 @@ DEF_TEST(Codec_Empty, r) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test_invalid_parameters(skiatest::Reporter* r, const char path[]) {
|
||||
std::unique_ptr<SkStream> stream(GetResourceAsStream(path));
|
||||
if (!stream) {
|
||||
return;
|
||||
}
|
||||
std::unique_ptr<SkCodec> decoder(SkCodec::NewFromStream(stream.release()));
|
||||
if (!decoder) {
|
||||
SkDebugf("Missing codec for %s\n", path);
|
||||
return;
|
||||
}
|
||||
|
||||
const SkImageInfo info = decoder->getInfo().makeColorType(kIndex_8_SkColorType);
|
||||
|
||||
// This should return kSuccess because kIndex8 is supported.
|
||||
SkPMColor colorStorage[256];
|
||||
int colorCount;
|
||||
SkCodec::Result result = decoder->startScanlineDecode(info, nullptr, colorStorage,
|
||||
&colorCount);
|
||||
if (SkCodec::kSuccess == result) {
|
||||
// This should return kInvalidParameters because, in kIndex_8 mode, we must pass in a valid
|
||||
// colorPtr and a valid colorCountPtr.
|
||||
result = decoder->startScanlineDecode(info, nullptr, nullptr, nullptr);
|
||||
REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
|
||||
result = decoder->startScanlineDecode(info);
|
||||
REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
|
||||
} else if (SkCodec::kUnimplemented == result) {
|
||||
// New method should be supported:
|
||||
SkBitmap bm;
|
||||
bm.allocPixels(info, SkColorTable::Make(colorStorage, 256));
|
||||
result = decoder->startIncrementalDecode(info, bm.getPixels(), bm.rowBytes(), nullptr,
|
||||
colorStorage, &colorCount);
|
||||
REPORTER_ASSERT(r, SkCodec::kSuccess == result);
|
||||
result = decoder->startIncrementalDecode(info, bm.getPixels(), bm.rowBytes());
|
||||
REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
|
||||
} else {
|
||||
// The test is uninteresting if kIndex8 is not supported
|
||||
ERRORF(r, "Should not call test_invalid_parameters for non-Index8 file: %s\n", path);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DEF_TEST(Codec_Params, r) {
|
||||
test_invalid_parameters(r, "index8.png");
|
||||
test_invalid_parameters(r, "mandrill.wbmp");
|
||||
}
|
||||
|
||||
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
|
||||
|
||||
#ifndef SK_PNG_DISABLE_TESTS // reading chunks does not work properly with older versions.
|
||||
@ -1102,14 +1053,8 @@ static bool alpha_type_match(SkAlphaType origAlphaType, SkAlphaType codecAlphaTy
|
||||
|
||||
static void check_round_trip(skiatest::Reporter* r, SkCodec* origCodec, const SkImageInfo& info) {
|
||||
SkBitmap bm1;
|
||||
SkPMColor colors[256];
|
||||
sk_sp<SkColorTable> colorTable1 = SkColorTable::Make(colors, 256);
|
||||
bm1.allocPixels(info, colorTable1);
|
||||
int numColors;
|
||||
SkCodec::Result result = origCodec->getPixels(info, bm1.getPixels(), bm1.rowBytes(), nullptr,
|
||||
const_cast<SkPMColor*>(colorTable1->readColors()),
|
||||
&numColors);
|
||||
// This will fail to update colorTable1->count() but is fine for the purpose of this test.
|
||||
bm1.allocPixels(info);
|
||||
SkCodec::Result result = origCodec->getPixels(info, bm1.getPixels(), bm1.rowBytes());
|
||||
REPORTER_ASSERT(r, SkCodec::kSuccess == result);
|
||||
|
||||
// Encode the image to png.
|
||||
@ -1121,10 +1066,8 @@ static void check_round_trip(skiatest::Reporter* r, SkCodec* origCodec, const Sk
|
||||
REPORTER_ASSERT(r, alpha_type_match(info.alphaType(), codec->getInfo().alphaType()));
|
||||
|
||||
SkBitmap bm2;
|
||||
sk_sp<SkColorTable> colorTable2 = SkColorTable::Make(colors, 256);
|
||||
bm2.allocPixels(info, colorTable2);
|
||||
result = codec->getPixels(info, bm2.getPixels(), bm2.rowBytes(), nullptr,
|
||||
const_cast<SkPMColor*>(colorTable2->readColors()), &numColors);
|
||||
bm2.allocPixels(info);
|
||||
result = codec->getPixels(info, bm2.getPixels(), bm2.rowBytes());
|
||||
REPORTER_ASSERT(r, SkCodec::kSuccess == result);
|
||||
|
||||
SkMD5::Digest d1, d2;
|
||||
@ -1251,7 +1194,7 @@ static void decode_frame(skiatest::Reporter* r, SkCodec* codec, size_t frame) {
|
||||
SkCodec::Options opts;
|
||||
opts.fFrameIndex = frame;
|
||||
REPORTER_ASSERT(r, SkCodec::kSuccess == codec->getPixels(info,
|
||||
bm.getPixels(), bm.rowBytes(), &opts, nullptr, nullptr));
|
||||
bm.getPixels(), bm.rowBytes(), &opts));
|
||||
}
|
||||
|
||||
// For an animated GIF, we should only read enough to decode frame 0 if the
|
||||
|
@ -238,25 +238,11 @@ DEF_TEST(Gif_Sampled, r) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Construct a color table for the decode if necessary
|
||||
sk_sp<SkColorTable> colorTable(nullptr);
|
||||
SkPMColor* colorPtr = nullptr;
|
||||
int* colorCountPtr = nullptr;
|
||||
int maxColors = 256;
|
||||
if (kIndex_8_SkColorType == codec->getInfo().colorType()) {
|
||||
SkPMColor colors[256];
|
||||
colorTable.reset(new SkColorTable(colors, maxColors));
|
||||
colorPtr = const_cast<SkPMColor*>(colorTable->readColors());
|
||||
colorCountPtr = &maxColors;
|
||||
}
|
||||
|
||||
SkAndroidCodec::AndroidOptions options;
|
||||
options.fSampleSize = 4;
|
||||
options.fColorPtr = colorPtr;
|
||||
options.fColorCount = colorCountPtr;
|
||||
|
||||
SkBitmap bm;
|
||||
bm.allocPixels(codec->getInfo(), colorTable);
|
||||
bm.allocPixels(codec->getInfo());
|
||||
const SkCodec::Result result = codec->getAndroidPixels(codec->getInfo(), bm.getPixels(),
|
||||
bm.rowBytes(), &options);
|
||||
REPORTER_ASSERT(r, result == SkCodec::kSuccess);
|
||||
@ -273,41 +259,3 @@ DEF_TEST(Codec_GifTruncated, r) {
|
||||
std::unique_ptr<SkCodec> codec(SkCodec::NewFromData(data));
|
||||
REPORTER_ASSERT(r, !codec);
|
||||
}
|
||||
|
||||
// There was a bug where SkAndroidCodec::computeOutputColorType returned kIndex_8 for
|
||||
// GIFs that did not support kIndex_8. Verify that for such an image, the method computes
|
||||
// something that it can actually decode to.
|
||||
DEF_TEST(Codec_GifIndex8, r) {
|
||||
std::unique_ptr<SkStream> stream(GetResourceAsStream("randPixelsOffset.gif"));
|
||||
if (!stream) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(stream.release()));
|
||||
REPORTER_ASSERT(r, codec);
|
||||
if (!codec) {
|
||||
return;
|
||||
}
|
||||
|
||||
REPORTER_ASSERT(r, codec->getInfo().colorType() == kN32_SkColorType);
|
||||
const SkColorType outputColorType = codec->computeOutputColorType(kN32_SkColorType);
|
||||
REPORTER_ASSERT(r, outputColorType == kN32_SkColorType);
|
||||
|
||||
SkAndroidCodec::AndroidOptions options;
|
||||
sk_sp<SkColorTable> colorTable(nullptr);
|
||||
int maxColors = 256;
|
||||
if (kIndex_8_SkColorType == outputColorType) {
|
||||
SkPMColor colors[256];
|
||||
colorTable.reset(new SkColorTable(colors, maxColors));
|
||||
options.fColorPtr = const_cast<SkPMColor*>(colorTable->readColors());
|
||||
options.fColorCount = &maxColors;
|
||||
}
|
||||
|
||||
auto info = codec->getInfo().makeColorType(outputColorType);
|
||||
SkBitmap bm;
|
||||
bm.setInfo(info);
|
||||
bm.allocPixels(colorTable.get());
|
||||
|
||||
REPORTER_ASSERT(r, SkCodec::kSuccess == codec->getAndroidPixels(info, bm.getPixels(),
|
||||
bm.rowBytes(), &options));
|
||||
}
|
||||
|
2
third_party/gif/SkGifImageReader.cpp
vendored
2
third_party/gif/SkGifImageReader.cpp
vendored
@ -762,13 +762,11 @@ bool SkGifImageReader::parse(SkGifImageReader::SkGIFParseQuery query)
|
||||
isLocalColormapDefined, numColors))
|
||||
{
|
||||
m_firstFrameHasAlpha = true;
|
||||
m_firstFrameSupportsIndex8 = true;
|
||||
} else {
|
||||
const bool frameIsSubset = xOffset > 0 || yOffset > 0
|
||||
|| width < fScreenWidth
|
||||
|| height < fScreenHeight;
|
||||
m_firstFrameHasAlpha = frameIsSubset;
|
||||
m_firstFrameSupportsIndex8 = !frameIsSubset;
|
||||
}
|
||||
}
|
||||
|
||||
|
8
third_party/gif/SkGifImageReader.h
vendored
8
third_party/gif/SkGifImageReader.h
vendored
@ -289,7 +289,6 @@ public:
|
||||
, m_streamBuffer(stream)
|
||||
, m_parseCompleted(false)
|
||||
, m_firstFrameHasAlpha(false)
|
||||
, m_firstFrameSupportsIndex8(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -367,8 +366,6 @@ public:
|
||||
|
||||
bool firstFrameHasAlpha() const { return m_firstFrameHasAlpha; }
|
||||
|
||||
bool firstFrameSupportsIndex8() const { return m_firstFrameSupportsIndex8; }
|
||||
|
||||
// Helper function that returns whether an SkGIFFrameContext has transparency.
|
||||
// This method is sometimes called before creating one/parsing its color map,
|
||||
// so it cannot rely on SkGIFFrameContext::transparentPixel or ::localColorMap().
|
||||
@ -410,10 +407,9 @@ private:
|
||||
SkStreamBuffer m_streamBuffer;
|
||||
bool m_parseCompleted;
|
||||
|
||||
// These values can be computed before we create a SkGIFFrameContext, so we
|
||||
// store them here instead of on m_frames[0].
|
||||
// This value can be computed before we create a SkGIFFrameContext, so we
|
||||
// store it here instead of on m_frames[0].
|
||||
bool m_firstFrameHasAlpha;
|
||||
bool m_firstFrameSupportsIndex8;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user