/* * Copyright 2009 The Android Open Source Project * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkImageEncoderPriv.h" #include "SkJpegEncoder.h" #include "SkPngEncoder.h" #include "SkWebpEncoder.h" #ifndef SK_HAS_JPEG_LIBRARY bool SkJpegEncoder::Encode(SkWStream*, const SkPixmap&, const Options&) { return false; } std::unique_ptr<SkEncoder> SkJpegEncoder::Make(SkWStream*, const SkPixmap&, const Options&) { return nullptr; } #endif #ifndef SK_HAS_PNG_LIBRARY bool SkPngEncoder::Encode(SkWStream*, const SkPixmap&, const Options&) { return false; } std::unique_ptr<SkEncoder> SkPngEncoder::Make(SkWStream*, const SkPixmap&, const Options&) { return nullptr; } #endif #ifndef SK_HAS_WEBP_LIBRARY bool SkWebpEncoder::Encode(SkWStream*, const SkPixmap&, const Options&) { return false; } #endif bool SkEncodeImage(SkWStream* dst, const SkPixmap& src, SkEncodedImageFormat format, int quality) { #ifdef SK_USE_CG_ENCODER (void)quality; return SkEncodeImageWithCG(dst, src, format); #elif SK_USE_WIC_ENCODER return SkEncodeImageWithWIC(dst, src, format, quality); #else switch(format) { case SkEncodedImageFormat::kJPEG: { SkJpegEncoder::Options opts; opts.fQuality = quality; return SkJpegEncoder::Encode(dst, src, opts); } case SkEncodedImageFormat::kPNG: { SkPngEncoder::Options opts; return SkPngEncoder::Encode(dst, src, opts); } case SkEncodedImageFormat::kWEBP: { SkWebpEncoder::Options opts; if (quality == 100) { opts.fCompression = SkWebpEncoder::Compression::kLossless; // Note: SkEncodeImage treats 0 quality as the lowest quality // (greatest compression) and 100 as the highest quality (least // compression). For kLossy, this matches libwebp's // interpretation, so it is passed directly to libwebp. But // with kLossless, libwebp always creates the highest quality // image. In this case, fQuality is reinterpreted as how much // effort (time) to put into making a smaller file. This API // does not provide a way to specify this value (though it can // be specified by using SkWebpEncoder::Encode) so we have to // pick one arbitrarily. This value matches that chosen by // blink::ImageEncoder::ComputeWebpOptions as well // WebPConfigInit. opts.fQuality = 75; } else { opts.fCompression = SkWebpEncoder::Compression::kLossy; opts.fQuality = quality; } return SkWebpEncoder::Encode(dst, src, opts); } default: return false; } #endif } bool SkEncoder::encodeRows(int numRows) { SkASSERT(numRows > 0 && fCurrRow < fSrc.height()); if (numRows <= 0 || fCurrRow >= fSrc.height()) { return false; } if (fCurrRow + numRows > fSrc.height()) { numRows = fSrc.height() - fCurrRow; } if (!this->onEncodeRows(numRows)) { // If we fail, short circuit any future calls. fCurrRow = fSrc.height(); return false; } return true; } sk_sp<SkData> SkEncodePixmap(const SkPixmap& src, SkEncodedImageFormat format, int quality) { SkDynamicMemoryWStream stream; return SkEncodeImage(&stream, src, format, quality) ? stream.detachAsData() : nullptr; } sk_sp<SkData> SkEncodeBitmap(const SkBitmap& src, SkEncodedImageFormat format, int quality) { SkPixmap pixmap; return src.peekPixels(&pixmap) ? SkEncodePixmap(pixmap, format, quality) : nullptr; }