@@ -79,49 +79,71 @@ float GetScaleFactorFromOptions(mate::Arguments* args) {
7979 return scale_factor;
8080}
8181
82- bool AddImageSkiaRep (gfx::ImageSkia* image,
83- const unsigned char * data,
84- size_t size,
85- int width,
86- int height,
87- double scale_factor) {
88- auto decoded = std::make_unique<SkBitmap>();
82+ bool AddImageSkiaRepFromPNG (gfx::ImageSkia* image,
83+ const unsigned char * data,
84+ size_t size,
85+ double scale_factor) {
86+ SkBitmap bitmap;
87+ if (!gfx::PNGCodec::Decode (data, size, &bitmap))
88+ return false ;
89+
90+ image->AddRepresentation (gfx::ImageSkiaRep (bitmap, scale_factor));
91+ return true ;
92+ }
93+
94+ bool AddImageSkiaRepFromJPEG (gfx::ImageSkia* image,
95+ const unsigned char * data,
96+ size_t size,
97+ double scale_factor) {
98+ auto bitmap = gfx::JPEGCodec::Decode (data, size);
99+ if (!bitmap)
100+ return false ;
101+
102+ // `JPEGCodec::Decode()` doesn't tell `SkBitmap` instance it creates
103+ // that all of its pixels are opaque, that's why the bitmap gets
104+ // an alpha type `kPremul_SkAlphaType` instead of `kOpaque_SkAlphaType`.
105+ // Let's fix it here.
106+ // TODO(alexeykuzmin): This workaround should be removed
107+ // when the `JPEGCodec::Decode()` code is fixed.
108+ // See https://github.com/electron/electron/issues/11294.
109+ bitmap->setAlphaType (SkAlphaType::kOpaque_SkAlphaType );
110+
111+ image->AddRepresentation (gfx::ImageSkiaRep (*bitmap, scale_factor));
112+ return true ;
113+ }
89114
115+ bool AddImageSkiaRepFromBuffer (gfx::ImageSkia* image,
116+ const unsigned char * data,
117+ size_t size,
118+ int width,
119+ int height,
120+ double scale_factor) {
90121 // Try PNG first.
91- if (!gfx::PNGCodec::Decode (data, size, decoded.get ())) {
92- // Try JPEG.
93- decoded = gfx::JPEGCodec::Decode (data, size);
94- if (decoded) {
95- // `JPEGCodec::Decode()` doesn't tell `SkBitmap` instance it creates
96- // that all of its pixels are opaque, that's why the bitmap gets
97- // an alpha type `kPremul_SkAlphaType` instead of `kOpaque_SkAlphaType`.
98- // Let's fix it here.
99- // TODO(alexeykuzmin): This workaround should be removed
100- // when the `JPEGCodec::Decode()` code is fixed.
101- // See https://github.com/electron/electron/issues/11294.
102- decoded->setAlphaType (SkAlphaType::kOpaque_SkAlphaType );
103- }
104- }
122+ if (AddImageSkiaRepFromPNG (image, data, size, scale_factor))
123+ return true ;
105124
106- if (!decoded) {
107- // Try Bitmap
108- if (width > 0 && height > 0 ) {
109- decoded.reset (new SkBitmap);
110- decoded->allocN32Pixels (width, height, false );
111- decoded->setPixels (
112- const_cast <void *>(reinterpret_cast <const void *>(data)));
113- } else {
114- return false ;
115- }
116- }
125+ // Try JPEG second.
126+ if (AddImageSkiaRepFromJPEG (image, data, size, scale_factor))
127+ return true ;
117128
118- image->AddRepresentation (gfx::ImageSkiaRep (*decoded, scale_factor));
129+ if (width == 0 || height == 0 )
130+ return false ;
131+
132+ auto info = SkImageInfo::MakeN32 (width, height, kPremul_SkAlphaType );
133+ if (size < info.computeMinByteSize ())
134+ return false ;
135+
136+ SkBitmap bitmap;
137+ bitmap.allocN32Pixels (width, height, false );
138+ bitmap.setPixels (const_cast <void *>(reinterpret_cast <const void *>(data)));
139+
140+ image->AddRepresentation (gfx::ImageSkiaRep (bitmap, scale_factor));
119141 return true ;
120142}
121143
122- bool AddImageSkiaRep (gfx::ImageSkia* image,
123- const base::FilePath& path,
124- double scale_factor) {
144+ bool AddImageSkiaRepFromPath (gfx::ImageSkia* image,
145+ const base::FilePath& path,
146+ double scale_factor) {
125147 std::string file_contents;
126148 {
127149 base::ThreadRestrictions::ScopedAllowIO allow_io;
@@ -132,7 +154,8 @@ bool AddImageSkiaRep(gfx::ImageSkia* image,
132154 const unsigned char * data =
133155 reinterpret_cast <const unsigned char *>(file_contents.data ());
134156 size_t size = file_contents.size ();
135- return AddImageSkiaRep (image, data, size, 0 , 0 , scale_factor);
157+
158+ return AddImageSkiaRepFromBuffer (image, data, size, 0 , 0 , scale_factor);
136159}
137160
138161bool PopulateImageSkiaRepsFromPath (gfx::ImageSkia* image,
@@ -141,12 +164,12 @@ bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image,
141164 std::string filename (path.BaseName ().RemoveExtension ().AsUTF8Unsafe ());
142165 if (base::MatchPattern (filename, " *@*x" ))
143166 // Don't search for other representations if the DPI has been specified.
144- return AddImageSkiaRep (image, path, GetScaleFactorFromPath (path));
167+ return AddImageSkiaRepFromPath (image, path, GetScaleFactorFromPath (path));
145168 else
146- succeed |= AddImageSkiaRep (image, path, 1 .0f );
169+ succeed |= AddImageSkiaRepFromPath (image, path, 1 .0f );
147170
148171 for (const ScaleFactorPair& pair : kScaleFactorPairs )
149- succeed |= AddImageSkiaRep (
172+ succeed |= AddImageSkiaRepFromPath (
150173 image, path.InsertBeforeExtensionASCII (pair.name ), pair.scale );
151174 return succeed;
152175}
@@ -422,19 +445,20 @@ void NativeImage::AddRepresentation(const mate::Dictionary& options) {
422445 v8::Local<v8::Value> buffer;
423446 GURL url;
424447 if (options.Get (" buffer" , &buffer) && node::Buffer::HasInstance (buffer)) {
425- AddImageSkiaRep (
426- &image_skia,
427- reinterpret_cast <unsigned char *>(node::Buffer::Data (buffer)),
428- node::Buffer::Length (buffer), width, height, scale_factor);
429- skia_rep_added = true ;
448+ auto * data = reinterpret_cast <unsigned char *>(node::Buffer::Data (buffer));
449+ auto size = node::Buffer::Length (buffer);
450+ skia_rep_added = AddImageSkiaRepFromBuffer (&image_skia, data, size, width,
451+ height, scale_factor);
430452 } else if (options.Get (" dataURL" , &url)) {
431453 std::string mime_type, charset, data;
432454 if (net::DataURL::Parse (url, &mime_type, &charset, &data)) {
433- if (mime_type == " image/png" || mime_type == " image/jpeg" ) {
434- AddImageSkiaRep (&image_skia,
435- reinterpret_cast <const unsigned char *>(data.c_str ()),
436- data.size (), width, height, scale_factor);
437- skia_rep_added = true ;
455+ auto * data_ptr = reinterpret_cast <const unsigned char *>(data.c_str ());
456+ if (mime_type == " image/png" ) {
457+ skia_rep_added = AddImageSkiaRepFromPNG (&image_skia, data_ptr,
458+ data.size (), scale_factor);
459+ } else if (mime_type == " image/jpeg" ) {
460+ skia_rep_added = AddImageSkiaRepFromJPEG (&image_skia, data_ptr,
461+ data.size (), scale_factor);
438462 }
439463 }
440464 }
@@ -525,9 +549,9 @@ mate::Handle<NativeImage> NativeImage::CreateFromBuffer(
525549 }
526550
527551 gfx::ImageSkia image_skia;
528- AddImageSkiaRep (&image_skia,
529- reinterpret_cast <unsigned char *>(node::Buffer::Data (buffer)),
530- node::Buffer::Length (buffer), width, height, scale_factor);
552+ AddImageSkiaRepFromBuffer (
553+ &image_skia, reinterpret_cast <unsigned char *>(node::Buffer::Data (buffer)),
554+ node::Buffer::Length (buffer), width, height, scale_factor);
531555 return Create (args->isolate (), gfx::Image (image_skia));
532556}
533557
0 commit comments