1 /* 2 * Copyright 2009 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkImageEncoderPriv.h" 9 #include "SkJpegEncoder.h" 10 #include "SkPngEncoder.h" 11 #include "SkWebpEncoder.h" 12 13 #ifndef SK_HAS_JPEG_LIBRARY 14 bool SkJpegEncoder::Encode(SkWStream*, const SkPixmap&, const Options&) { return false; } 15 std::unique_ptr<SkEncoder> SkJpegEncoder::Make(SkWStream*, const SkPixmap&, const Options&) { 16 return nullptr; 17 } 18 #endif 19 20 #ifndef SK_HAS_PNG_LIBRARY 21 bool SkPngEncoder::Encode(SkWStream*, const SkPixmap&, const Options&) { return false; } 22 std::unique_ptr<SkEncoder> SkPngEncoder::Make(SkWStream*, const SkPixmap&, const Options&) { 23 return nullptr; 24 } 25 #endif 26 27 #ifndef SK_HAS_WEBP_LIBRARY 28 bool SkWebpEncoder::Encode(SkWStream*, const SkPixmap&, const Options&) { return false; } 29 #endif 30 31 bool SkEncodeImage(SkWStream* dst, const SkPixmap& src, 32 SkEncodedImageFormat format, int quality) { 33 #ifdef SK_USE_CG_ENCODER 34 (void)quality; 35 return SkEncodeImageWithCG(dst, src, format); 36 #elif SK_USE_WIC_ENCODER 37 return SkEncodeImageWithWIC(dst, src, format, quality); 38 #else 39 switch(format) { 40 case SkEncodedImageFormat::kJPEG: { 41 SkJpegEncoder::Options opts; 42 opts.fQuality = quality; 43 return SkJpegEncoder::Encode(dst, src, opts); 44 } 45 case SkEncodedImageFormat::kPNG: { 46 SkPngEncoder::Options opts; 47 return SkPngEncoder::Encode(dst, src, opts); 48 } 49 case SkEncodedImageFormat::kWEBP: { 50 SkWebpEncoder::Options opts; 51 if (quality == 100) { 52 opts.fCompression = SkWebpEncoder::Compression::kLossless; 53 // Note: SkEncodeImage treats 0 quality as the lowest quality 54 // (greatest compression) and 100 as the highest quality (least 55 // compression). For kLossy, this matches libwebp's 56 // interpretation, so it is passed directly to libwebp. But 57 // with kLossless, libwebp always creates the highest quality 58 // image. In this case, fQuality is reinterpreted as how much 59 // effort (time) to put into making a smaller file. This API 60 // does not provide a way to specify this value (though it can 61 // be specified by using SkWebpEncoder::Encode) so we have to 62 // pick one arbitrarily. This value matches that chosen by 63 // blink::ImageEncoder::ComputeWebpOptions as well 64 // WebPConfigInit. 65 opts.fQuality = 75; 66 } else { 67 opts.fCompression = SkWebpEncoder::Compression::kLossy; 68 opts.fQuality = quality; 69 } 70 return SkWebpEncoder::Encode(dst, src, opts); 71 } 72 default: 73 return false; 74 } 75 #endif 76 } 77 78 bool SkEncoder::encodeRows(int numRows) { 79 SkASSERT(numRows > 0 && fCurrRow < fSrc.height()); 80 if (numRows <= 0 || fCurrRow >= fSrc.height()) { 81 return false; 82 } 83 84 if (fCurrRow + numRows > fSrc.height()) { 85 numRows = fSrc.height() - fCurrRow; 86 } 87 88 if (!this->onEncodeRows(numRows)) { 89 // If we fail, short circuit any future calls. 90 fCurrRow = fSrc.height(); 91 return false; 92 } 93 94 return true; 95 } 96 97 sk_sp<SkData> SkEncodePixmap(const SkPixmap& src, SkEncodedImageFormat format, int quality) { 98 SkDynamicMemoryWStream stream; 99 return SkEncodeImage(&stream, src, format, quality) ? stream.detachAsData() : nullptr; 100 } 101 102 sk_sp<SkData> SkEncodeBitmap(const SkBitmap& src, SkEncodedImageFormat format, int quality) { 103 SkPixmap pixmap; 104 return src.peekPixels(&pixmap) ? SkEncodePixmap(pixmap, format, quality) : nullptr; 105 } 106