File: image_encoder.cc

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (133 lines) | stat: -rw-r--r-- 4,215 bytes parent folder | download | duplicates (5)
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