1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/image-encoders/image_encoder.h"
#include "base/notreached.h"
#include "build/build_config.h"
#include "skia/rusty_png_feature.h"
#if BUILDFLAG(IS_WIN)
#include <basetsd.h> // Included before jpeglib.h because of INT32 clash
#endif
#include <stdio.h> // Needed by jpeglib.h
#include "jpeglib.h" // for JPEG_MAX_DIMENSION
#include "third_party/libwebp/src/src/webp/encode.h" // for WEBP_MAX_DIMENSION
namespace blink {
bool ImageEncoder::Encode(Vector<unsigned char>* dst,
const SkPixmap& src,
const SkJpegEncoder::Options& options) {
VectorWStream dst_stream(dst);
return SkJpegEncoder::Encode(&dst_stream, src, options);
}
bool ImageEncoder::Encode(Vector<unsigned char>* dst,
const SkPixmap& src,
const SkPngEncoder::Options& options) {
VectorWStream dst_stream(dst);
return skia::EncodePng(&dst_stream, src, options);
}
bool ImageEncoder::Encode(Vector<unsigned char>* dst,
const SkPixmap& src,
const SkWebpEncoder::Options& options) {
VectorWStream dst_stream(dst);
return SkWebpEncoder::Encode(&dst_stream, src, options);
}
bool ImageEncoder::Encode(Vector<unsigned char>* dst,
const SkPixmap& src,
ImageEncodingMimeType mime_type,
double quality) {
switch (mime_type) {
case kMimeTypeJpeg: {
SkJpegEncoder::Options options;
options.fQuality = ComputeJpegQuality(quality);
options.fAlphaOption = SkJpegEncoder::AlphaOption::kBlendOnBlack;
if (options.fQuality == 100) {
options.fDownsample = SkJpegEncoder::Downsample::k444;
}
return Encode(dst, src, options);
}
case kMimeTypeWebp: {
SkWebpEncoder::Options options = ComputeWebpOptions(quality);
return Encode(dst, src, options);
}
case kMimeTypePng: {
SkPngEncoder::Options options;
options.fFilterFlags = SkPngEncoder::FilterFlag::kSub;
options.fZLibLevel = 3;
return Encode(dst, src, options);
}
}
}
std::unique_ptr<ImageEncoder> ImageEncoder::Create(
Vector<unsigned char>* dst,
const SkPixmap& src,
const SkJpegEncoder::Options& options) {
std::unique_ptr<ImageEncoder> image_encoder(new ImageEncoder(dst));
image_encoder->encoder_ =
SkJpegEncoder::Make(&image_encoder->dst_, src, options);
if (!image_encoder->encoder_) {
return nullptr;
}
return image_encoder;
}
std::unique_ptr<ImageEncoder> ImageEncoder::Create(
Vector<unsigned char>* dst,
const SkPixmap& src,
const SkPngEncoder::Options& options) {
std::unique_ptr<ImageEncoder> image_encoder(new ImageEncoder(dst));
image_encoder->encoder_ =
skia::MakePngEncoder(&image_encoder->dst_, src, options);
if (!image_encoder->encoder_) {
return nullptr;
}
return image_encoder;
}
int ImageEncoder::MaxDimension(ImageEncodingMimeType mime_type) {
switch (mime_type) {
case kMimeTypePng:
return 65535;
case kMimeTypeJpeg:
return JPEG_MAX_DIMENSION;
case kMimeTypeWebp:
return WEBP_MAX_DIMENSION;
default:
NOTREACHED();
}
}
int ImageEncoder::ComputeJpegQuality(double quality) {
int compression_quality = 92; // Default value
if (0.0f <= quality && quality <= 1.0)
compression_quality = static_cast<int>(quality * 100 + 0.5);
return compression_quality;
}
SkWebpEncoder::Options ImageEncoder::ComputeWebpOptions(double quality) {
SkWebpEncoder::Options options;
if (quality == 1.0) {
// Choose a lossless encode. When performing a lossless encode, higher
// quality corresponds to slower encoding and smaller output size.
options.fCompression = SkWebpEncoder::Compression::kLossless;
options.fQuality = 75.0f;
} else {
options.fQuality = 80.0f; // Default value
if (0.0f <= quality && quality <= 1.0)
options.fQuality = quality * 100.0f;
}
return options;
}
} // namespace blink
|