add runtime registration for encoders
If we want to make these external dependencies mix-and-match in Google3, we'll need to group together the encoders and decoders, everything that dependends on each external library. I was tempted to try to remove these generic encoder entrypoints and replace them with calls to the direct equivalents, but I'm not sure that's necessary. I think we can just register encoders like decoders. Change-Id: I41d2d1bb3ceb1daafa62c95d345eb6a70249be75 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/213880 Commit-Queue: Mike Klein <mtklein@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
753836fcad
commit
940c3f136d
@ -15,6 +15,9 @@
|
|||||||
#include "include/core/SkDocument.h"
|
#include "include/core/SkDocument.h"
|
||||||
#include "include/core/SkFontMgr.h"
|
#include "include/core/SkFontMgr.h"
|
||||||
#include "include/core/SkGraphics.h"
|
#include "include/core/SkGraphics.h"
|
||||||
|
#include "include/encode/SkJpegEncoder.h"
|
||||||
|
#include "include/encode/SkPngEncoder.h"
|
||||||
|
#include "include/encode/SkWebpEncoder.h"
|
||||||
#include "include/ports/SkTypeface_win.h"
|
#include "include/ports/SkTypeface_win.h"
|
||||||
#include "include/private/SkChecksum.h"
|
#include "include/private/SkChecksum.h"
|
||||||
#include "include/private/SkHalf.h"
|
#include "include/private/SkHalf.h"
|
||||||
@ -1394,6 +1397,10 @@ int main(int argc, char** argv) {
|
|||||||
SkCodec::Register( SkPngCodec::IsPng , SkPngCodec::MakeFromStream);
|
SkCodec::Register( SkPngCodec::IsPng , SkPngCodec::MakeFromStream);
|
||||||
SkCodec::Register(SkWebpCodec::IsWebp, SkWebpCodec::MakeFromStream);
|
SkCodec::Register(SkWebpCodec::IsWebp, SkWebpCodec::MakeFromStream);
|
||||||
|
|
||||||
|
SkRegisterEncoder(SkEncodedImageFormat::kJPEG, SkJpegEncoder::Encode);
|
||||||
|
SkRegisterEncoder(SkEncodedImageFormat::kPNG , SkPngEncoder::Encode);
|
||||||
|
SkRegisterEncoder(SkEncodedImageFormat::kWEBP, SkWebpEncoder::Encode);
|
||||||
|
|
||||||
initializeEventTracingForTools();
|
initializeEventTracingForTools();
|
||||||
|
|
||||||
#if !defined(SK_BUILD_FOR_GOOGLE3) && defined(SK_BUILD_FOR_IOS)
|
#if !defined(SK_BUILD_FOR_GOOGLE3) && defined(SK_BUILD_FOR_IOS)
|
||||||
|
@ -44,6 +44,16 @@ inline bool SkEncodeImage(SkWStream* dst, const SkBitmap& src, SkEncodedImageFor
|
|||||||
return src.peekPixels(&pixmap) && SkEncodeImage(dst, pixmap, f, q);
|
return src.peekPixels(&pixmap) && SkEncodeImage(dst, pixmap, f, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an encoder for a given binary image format.
|
||||||
|
*
|
||||||
|
* This encoder may be used by SkEncodeImage / SkEncodePixmap / SkEncodeBitmap.
|
||||||
|
*
|
||||||
|
* Not thread safe.
|
||||||
|
*/
|
||||||
|
SK_API void SkRegisterEncoder(SkEncodedImageFormat fmt,
|
||||||
|
bool(*)(SkWStream*, const SkPixmap&, int quality));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode SkPixmap in the given binary image format.
|
* Encode SkPixmap in the given binary image format.
|
||||||
*
|
*
|
||||||
|
@ -71,6 +71,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
static bool Encode(SkWStream* dst, const SkPixmap& src, const Options& options);
|
static bool Encode(SkWStream* dst, const SkPixmap& src, const Options& options);
|
||||||
|
|
||||||
|
static bool Encode(SkWStream* dst, const SkPixmap& src, int quality) {
|
||||||
|
Options options;
|
||||||
|
options.fQuality = quality;
|
||||||
|
return Encode(dst, src, options);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a jpeg encoder that will encode the |src| pixels to the |dst| stream.
|
* Create a jpeg encoder that will encode the |src| pixels to the |dst| stream.
|
||||||
* |options| may be used to control the encoding behavior.
|
* |options| may be used to control the encoding behavior.
|
||||||
|
@ -69,6 +69,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
static bool Encode(SkWStream* dst, const SkPixmap& src, const Options& options);
|
static bool Encode(SkWStream* dst, const SkPixmap& src, const Options& options);
|
||||||
|
|
||||||
|
static bool Encode(SkWStream* dst, const SkPixmap& src, int /*quality*/) {
|
||||||
|
return Encode(dst, src, Options{});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a png encoder that will encode the |src| pixels to the |dst| stream.
|
* Create a png encoder that will encode the |src| pixels to the |dst| stream.
|
||||||
* |options| may be used to control the encoding behavior.
|
* |options| may be used to control the encoding behavior.
|
||||||
|
@ -43,6 +43,20 @@ namespace SkWebpEncoder {
|
|||||||
* Returns true on success. Returns false on an invalid or unsupported |src|.
|
* Returns true on success. Returns false on an invalid or unsupported |src|.
|
||||||
*/
|
*/
|
||||||
SK_API bool Encode(SkWStream* dst, const SkPixmap& src, const Options& options);
|
SK_API bool Encode(SkWStream* dst, const SkPixmap& src, const Options& options);
|
||||||
|
|
||||||
|
inline bool Encode(SkWStream* dst, const SkPixmap& src, int quality) {
|
||||||
|
SkWebpEncoder::Options opts;
|
||||||
|
if (quality == 100) {
|
||||||
|
// fQuality acts as a signal for how much time to invest encoding a smaller file.
|
||||||
|
// This value matches blink::ImageEncoder::ComputeWebpOptions and WebPConfigInit.
|
||||||
|
opts.fQuality = 75;
|
||||||
|
opts.fCompression = SkWebpEncoder::Compression::kLossless;
|
||||||
|
} else {
|
||||||
|
opts.fQuality = quality;
|
||||||
|
opts.fCompression = SkWebpEncoder::Compression::kLossy;
|
||||||
|
}
|
||||||
|
return SkWebpEncoder::Encode(dst, src, opts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,24 +9,34 @@
|
|||||||
#include "include/encode/SkPngEncoder.h"
|
#include "include/encode/SkPngEncoder.h"
|
||||||
#include "include/encode/SkWebpEncoder.h"
|
#include "include/encode/SkWebpEncoder.h"
|
||||||
#include "src/images/SkImageEncoderPriv.h"
|
#include "src/images/SkImageEncoderPriv.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#ifndef SK_HAS_JPEG_LIBRARY
|
struct EncoderProc {
|
||||||
bool SkJpegEncoder::Encode(SkWStream*, const SkPixmap&, const Options&) { return false; }
|
SkEncodedImageFormat format;
|
||||||
std::unique_ptr<SkEncoder> SkJpegEncoder::Make(SkWStream*, const SkPixmap&, const Options&) {
|
bool (*encode)(SkWStream*, const SkPixmap&, int quality);
|
||||||
return nullptr;
|
};
|
||||||
|
|
||||||
|
static std::vector<EncoderProc>* encoders() {
|
||||||
|
static auto* encoders = new std::vector<EncoderProc> {
|
||||||
|
#ifdef SK_HAS_JPEG_LIBRARY
|
||||||
|
{ SkEncodedImageFormat::kJPEG, SkJpegEncoder::Encode },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SK_HAS_PNG_LIBRARY
|
||||||
|
{ SkEncodedImageFormat::kPNG, SkPngEncoder::Encode },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SK_HAS_WEBP_LIBRARY
|
||||||
|
{ SkEncodedImageFormat::kWEBP, SkWebpEncoder::Encode },
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
return encoders;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SK_HAS_PNG_LIBRARY
|
void SkRegisterEncoder(SkEncodedImageFormat format,
|
||||||
bool SkPngEncoder::Encode(SkWStream*, const SkPixmap&, const Options&) { return false; }
|
bool (*encode)(SkWStream*, const SkPixmap&, int)) {
|
||||||
std::unique_ptr<SkEncoder> SkPngEncoder::Make(SkWStream*, const SkPixmap&, const Options&) {
|
encoders()->push_back({format, encode});
|
||||||
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,
|
bool SkEncodeImage(SkWStream* dst, const SkPixmap& src,
|
||||||
SkEncodedImageFormat format, int quality) {
|
SkEncodedImageFormat format, int quality) {
|
||||||
@ -36,42 +46,12 @@ bool SkEncodeImage(SkWStream* dst, const SkPixmap& src,
|
|||||||
#elif SK_USE_WIC_ENCODER
|
#elif SK_USE_WIC_ENCODER
|
||||||
return SkEncodeImageWithWIC(dst, src, format, quality);
|
return SkEncodeImageWithWIC(dst, src, format, quality);
|
||||||
#else
|
#else
|
||||||
switch(format) {
|
for (auto encoder : *encoders()) {
|
||||||
case SkEncodedImageFormat::kJPEG: {
|
if (encoder.format == format) {
|
||||||
SkJpegEncoder::Options opts;
|
return encoder.encode(dst, src, quality);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user