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