Repository: electron/electron
Pull request: fix: -Wunsafe-buffer-usage warnings in GdkPixbufFromSkBitmap()

#### Description of Change

OK, now that #43938 has some tests in place for `GdkPixbufFromSkBitmap()`... This is part 8 in a [series](https://github.com/electron/electron/pull/43477) to fix `-Wunsafe-buffer-usage` warnings in electron `shell/`. This one fixes these `GdkPixbufFromSkBitmap()` warnings:

```
../../electron/shell/browser/ui/gtk_util.cc:87:31: error: unsafe buffer access [-Werror,-Wunsafe-buffer-usage]
   87 |       uint32_t pixel = bitmap.getAddr32(0, y)[x];
      |                        ~~~~~~~^~~~~~~~~~~~~~~
../../electron/shell/browser/ui/gtk_util.cc:87:31: note: pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions
../../electron/shell/browser/ui/gtk_util.cc:92:9: error: unsafe buffer access [-Werror,-Wunsafe-buffer-usage]
   92 |         divided[i + 0] = SkColorGetR(unmultiplied);
      |         ^~~~~~~
../../electron/shell/browser/ui/gtk_util.cc:92:9: note: pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions
../../electron/shell/browser/ui/gtk_util.cc:93:9: error: unsafe buffer access [-Werror,-Wunsafe-buffer-usage]
   93 |         divided[i + 1] = SkColorGetG(unmultiplied);
      |         ^~~~~~~
../../electron/shell/browser/ui/gtk_util.cc:93:9: note: pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions
../../electron/shell/browser/ui/gtk_util.cc:94:9: error: unsafe buffer access [-Werror,-Wunsafe-buffer-usage]
   94 |         divided[i + 2] = SkColorGetB(unmultiplied);
      |         ^~~~~~~
../../electron/shell/browser/ui/gtk_util.cc:94:9: note: pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions
../../electron/shell/browser/ui/gtk_util.cc:95:9: error: unsafe buffer access [-Werror,-Wunsafe-buffer-usage]
   95 |         divided[i + 3] = alpha;
      |         ^~~~~~~
../../electron/shell/browser/ui/gtk_util.cc:95:9: note: pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions
../../electron/shell/browser/ui/gtk_util.cc:97:9: error: unsafe buffer access [-Werror,-Wunsafe-buffer-usage]
   97 |         divided[i + 0] = SkColorGetR(pixel);
      |         ^~~~~~~
../../electron/shell/browser/ui/gtk_util.cc:97:9: note: pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions
../../electron/shell/browser/ui/gtk_util.cc:98:9: error: unsafe buffer access [-Werror,-Wunsafe-buffer-usage]
   98 |         divided[i + 1] = SkColorGetG(pixel);
      |         ^~~~~~~
../../electron/shell/browser/ui/gtk_util.cc:98:9: note: pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions
../../electron/shell/browser/ui/gtk_util.cc:99:9: error: unsafe buffer access [-Werror,-Wunsafe-buffer-usage]
   99 |         divided[i + 2] = SkColorGetB(pixel);
      |         ^~~~~~~
../../electron/shell/browser/ui/gtk_util.cc:99:9: note: pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions
../../electron/shell/browser/ui/gtk_util.cc:100:9: error: unsafe buffer access [-Werror,-Wunsafe-buffer-usage]
  100 |         divided[i + 3] = alpha;
      |         ^~~~~~~
../../electron/shell/browser/ui/gtk_util.cc:100:9: note: pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions
```

Implementation note: `SkUnPreMultiply::PMColorToColor()` is no longer needed because we're now calling `SkBItmap.getColor()`, which does alpha handling & unpremultiplication for us

#### Checklist

- [x] PR description included and stakeholders cc'd
- [x] `npm test` passes
- [x] [PR release notes](https://github.com/electron/clerk/blob/main/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/main/README.md#examples).

#### Release Notes

Notes: none.

Changed files:
filename: shell/browser/ui/gtk_util.cc
patch: @@ -9,6 +9,7 @@
 #include <stdint.h>
 
 #include <string>
+#include <vector>
 
 #include "base/no_destructor.h"
 #include "base/strings/string_number_conversions.h"
@@ -68,42 +69,30 @@ const char* GetYesLabel() {
 
 GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap& bitmap) {
   if (bitmap.isNull())
-    return nullptr;
-
-  int width = bitmap.width();
-  int height = bitmap.height();
-
-  GdkPixbuf* pixbuf =
-      gdk_pixbuf_new(GDK_COLORSPACE_RGB,  // The only colorspace gtk supports.
-                     TRUE,                // There is an alpha channel.
-                     8, width, height);
-
-  // SkBitmaps are premultiplied, we need to unpremultiply them.
-  const int kBytesPerPixel = 4;
-  uint8_t* divided = gdk_pixbuf_get_pixels(pixbuf);
-
-  for (int y = 0, i = 0; y < height; y++) {
-    for (int x = 0; x < width; x++) {
-      uint32_t pixel = bitmap.getAddr32(0, y)[x];
-
-      int alpha = SkColorGetA(pixel);
-      if (alpha != 0 && alpha != 255) {
-        SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel);
-        divided[i + 0] = SkColorGetR(unmultiplied);
-        divided[i + 1] = SkColorGetG(unmultiplied);
-        divided[i + 2] = SkColorGetB(unmultiplied);
-        divided[i + 3] = alpha;
-      } else {
-        divided[i + 0] = SkColorGetR(pixel);
-        divided[i + 1] = SkColorGetG(pixel);
-        divided[i + 2] = SkColorGetB(pixel);
-        divided[i + 3] = alpha;
-      }
-      i += kBytesPerPixel;
+    return {};
+
+  constexpr int kBytesPerPixel = 4;
+  const auto [width, height] = bitmap.dimensions();
+  std::vector<uint8_t> bytes;
+  bytes.reserve(width * height * kBytesPerPixel);
+  for (int y = 0; y < height; ++y) {
+    for (int x = 0; x < width; ++x) {
+      const SkColor pixel = bitmap.getColor(x, y);
+      bytes.emplace_back(SkColorGetR(pixel));
+      bytes.emplace_back(SkColorGetG(pixel));
+      bytes.emplace_back(SkColorGetB(pixel));
+      bytes.emplace_back(SkColorGetA(pixel));
     }
   }
 
-  return pixbuf;
+  constexpr GdkColorspace kColorspace = GDK_COLORSPACE_RGB;
+  constexpr gboolean kHasAlpha = true;
+  constexpr int kBitsPerSample = 8;
+  return gdk_pixbuf_new_from_bytes(
+      g_bytes_new(std::data(bytes), std::size(bytes)), kColorspace, kHasAlpha,
+      kBitsPerSample, width, height,
+      gdk_pixbuf_calculate_rowstride(kColorspace, kHasAlpha, kBitsPerSample,
+                                     width, height));
 }
 
 }  // namespace gtk_util