xref: /aosp_15_r20/external/skia/tools/EncodeUtils.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2023 Google LLC
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 "tools/EncodeUtils.h"
9 
10 #include "include/core/SkBitmap.h"
11 #include "include/core/SkData.h"
12 #include "include/core/SkDataTable.h"
13 #include "include/core/SkPixmap.h"
14 #include "include/core/SkRefCnt.h"
15 #include "include/core/SkStream.h"
16 #include "include/core/SkString.h"
17 #include "include/encode/SkPngEncoder.h"
18 #include "src/base/SkBase64.h"
19 
20 #include <cstddef>
21 #include <cstdint>
22 
23 namespace ToolUtils {
24 
BitmapToBase64DataURI(const SkBitmap & bitmap,SkString * dst)25 bool BitmapToBase64DataURI(const SkBitmap& bitmap, SkString* dst) {
26     SkPixmap pm;
27     if (!bitmap.peekPixels(&pm)) {
28         dst->set("peekPixels failed");
29         return false;
30     }
31 
32     // We're going to embed this PNG in a data URI, so make it as small as possible
33     SkPngEncoder::Options options;
34     options.fFilterFlags = SkPngEncoder::FilterFlag::kAll;
35     options.fZLibLevel = 9;
36 
37     SkDynamicMemoryWStream wStream;
38     if (!SkPngEncoder::Encode(&wStream, pm, options)) {
39         dst->set("SkPngEncoder::Encode failed");
40         return false;
41     }
42 
43     sk_sp<SkData> pngData = wStream.detachAsData();
44     size_t len = SkBase64::EncodedSize(pngData->size());
45 
46     // The PNG can be almost arbitrarily large. We don't want to fill our logs with enormous URLs.
47     // Infra says these can be pretty big, as long as we're only outputting them on failure.
48     static const size_t kMaxBase64Length = 1024 * 1024;
49     if (len > kMaxBase64Length) {
50         dst->printf("Encoded image too large (%u bytes)", static_cast<uint32_t>(len));
51         return false;
52     }
53 
54     dst->resize(len);
55     SkBase64::Encode(pngData->data(), pngData->size(), dst->data());
56     dst->prepend("data:image/png;base64,");
57     return true;
58 }
59 
EncodeImageToPngFile(const char * path,const SkBitmap & src)60 bool EncodeImageToPngFile(const char* path, const SkBitmap& src) {
61     SkFILEWStream file(path);
62     return file.isValid() && SkPngEncoder::Encode(&file, src.pixmap(), {});
63 }
64 
EncodeImageToPngFile(const char * path,const SkPixmap & src)65 bool EncodeImageToPngFile(const char* path, const SkPixmap& src) {
66     SkFILEWStream file(path);
67     return file.isValid() && SkPngEncoder::Encode(&file, src, {});
68 }
69 
70 }  // namespace ToolUtils
71