OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/frame/ImageBitmap.h" | 5 #include "core/frame/ImageBitmap.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include "core/html/HTMLCanvasElement.h" | 8 #include "core/html/HTMLCanvasElement.h" |
9 #include "core/html/HTMLVideoElement.h" | 9 #include "core/html/HTMLVideoElement.h" |
10 #include "core/html/ImageData.h" | 10 #include "core/html/ImageData.h" |
11 #include "core/offscreencanvas/OffscreenCanvas.h" | 11 #include "core/offscreencanvas/OffscreenCanvas.h" |
12 #include "platform/graphics/CanvasColorParams.h" | 12 #include "platform/graphics/CanvasColorParams.h" |
13 #include "platform/graphics/skia/SkiaUtils.h" | 13 #include "platform/graphics/skia/SkiaUtils.h" |
14 #include "platform/image-decoders/ImageDecoder.h" | 14 #include "platform/image-decoders/ImageDecoder.h" |
15 #include "platform/wtf/CheckedNumeric.h" | 15 #include "platform/wtf/CheckedNumeric.h" |
16 #include "platform/wtf/PtrUtil.h" | 16 #include "platform/wtf/PtrUtil.h" |
17 #include "platform/wtf/RefPtr.h" | 17 #include "platform/wtf/RefPtr.h" |
18 #include "third_party/skia/include/core/SkCanvas.h" | 18 #include "third_party/skia/include/core/SkCanvas.h" |
19 #include "third_party/skia/include/core/SkImageInfo.h" | 19 #include "third_party/skia/include/core/SkImageInfo.h" |
20 #include "third_party/skia/include/core/SkSurface.h" | 20 #include "third_party/skia/include/core/SkSurface.h" |
| 21 #include "third_party/skia/include/core/SkSwizzle.h" |
21 | 22 |
22 namespace blink { | 23 namespace blink { |
23 | 24 |
24 constexpr const char* kImageOrientationFlipY = "flipY"; | 25 constexpr const char* kImageOrientationFlipY = "flipY"; |
25 constexpr const char* kImageBitmapOptionNone = "none"; | 26 constexpr const char* kImageBitmapOptionNone = "none"; |
26 constexpr const char* kImageBitmapOptionDefault = "default"; | 27 constexpr const char* kImageBitmapOptionDefault = "default"; |
27 constexpr const char* kImageBitmapOptionPremultiply = "premultiply"; | 28 constexpr const char* kImageBitmapOptionPremultiply = "premultiply"; |
28 constexpr const char* kImageBitmapOptionResizeQualityHigh = "high"; | 29 constexpr const char* kImageBitmapOptionResizeQualityHigh = "high"; |
29 constexpr const char* kImageBitmapOptionResizeQualityMedium = "medium"; | 30 constexpr const char* kImageBitmapOptionResizeQualityMedium = "medium"; |
30 constexpr const char* kImageBitmapOptionResizeQualityPixelated = "pixelated"; | 31 constexpr const char* kImageBitmapOptionResizeQualityPixelated = "pixelated"; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 parsed_options.resize_quality = kHigh_SkFilterQuality; | 146 parsed_options.resize_quality = kHigh_SkFilterQuality; |
146 else if (options.resizeQuality() == kImageBitmapOptionResizeQualityMedium) | 147 else if (options.resizeQuality() == kImageBitmapOptionResizeQualityMedium) |
147 parsed_options.resize_quality = kMedium_SkFilterQuality; | 148 parsed_options.resize_quality = kMedium_SkFilterQuality; |
148 else if (options.resizeQuality() == kImageBitmapOptionResizeQualityPixelated) | 149 else if (options.resizeQuality() == kImageBitmapOptionResizeQualityPixelated) |
149 parsed_options.resize_quality = kNone_SkFilterQuality; | 150 parsed_options.resize_quality = kNone_SkFilterQuality; |
150 else | 151 else |
151 parsed_options.resize_quality = kLow_SkFilterQuality; | 152 parsed_options.resize_quality = kLow_SkFilterQuality; |
152 return parsed_options; | 153 return parsed_options; |
153 } | 154 } |
154 | 155 |
| 156 // The function dstBufferSizeHasOverflow() is being called at the beginning of |
| 157 // each ImageBitmap() constructor, which makes sure that doing |
| 158 // width * height * bytesPerPixel will never overflow unsigned. |
155 bool DstBufferSizeHasOverflow(const ParsedOptions& options) { | 159 bool DstBufferSizeHasOverflow(const ParsedOptions& options) { |
156 CheckedNumeric<unsigned> total_bytes = options.crop_rect.Width(); | 160 CheckedNumeric<unsigned> total_bytes = options.crop_rect.Width(); |
157 total_bytes *= options.crop_rect.Height(); | 161 total_bytes *= options.crop_rect.Height(); |
158 total_bytes *= | 162 total_bytes *= |
159 SkColorTypeBytesPerPixel(options.color_params.GetSkColorType()); | 163 SkColorTypeBytesPerPixel(options.color_params.GetSkColorType()); |
160 if (!total_bytes.IsValid()) | 164 if (!total_bytes.IsValid()) |
161 return true; | 165 return true; |
162 | 166 |
163 if (!options.should_scale_input) | 167 if (!options.should_scale_input) |
164 return false; | 168 return false; |
165 total_bytes = options.resize_width; | 169 total_bytes = options.resize_width; |
166 total_bytes *= options.resize_height; | 170 total_bytes *= options.resize_height; |
167 total_bytes *= | 171 total_bytes *= |
168 SkColorTypeBytesPerPixel(options.color_params.GetSkColorType()); | 172 SkColorTypeBytesPerPixel(options.color_params.GetSkColorType()); |
169 if (!total_bytes.IsValid()) | 173 if (!total_bytes.IsValid()) |
170 return true; | 174 return true; |
171 | 175 |
172 return false; | 176 return false; |
173 } | 177 } |
174 | 178 |
175 } // namespace | 179 } // namespace |
176 | 180 |
| 181 static void PrintSkImage(sk_sp<SkImage> input) { |
| 182 SkImageInfo info = |
| 183 SkImageInfo::Make(input->width(), input->height(), kN32_SkColorType, |
| 184 kPremul_SkAlphaType, input->refColorSpace()); |
| 185 LOG(ERROR) << "Printing SkImage:" << input->width() << "," << input->height(); |
| 186 std::stringstream str; |
| 187 std::unique_ptr<uint8_t[]> read_pixels( |
| 188 new uint8_t[input->width() * input->height() * 4]()); |
| 189 input->readPixels(info, read_pixels.get(), input->width() * 4, 0, 0); |
| 190 for (int i = 0; i < input->width() * input->height(); i++) { |
| 191 if (i % input->width() == 0) |
| 192 str << "\n"; |
| 193 str << "["; |
| 194 for (int j = 0; j < 4; j++) |
| 195 str << (int)(read_pixels[i * 4 + j]) << ","; |
| 196 str << "] "; |
| 197 } |
| 198 LOG(ERROR) << str.str(); |
| 199 } |
| 200 |
177 static PassRefPtr<Uint8Array> CopySkImageData(SkImage* input, | 201 static PassRefPtr<Uint8Array> CopySkImageData(SkImage* input, |
178 const SkImageInfo& info) { | 202 const SkImageInfo& info) { |
179 // The function dstBufferSizeHasOverflow() is being called at the beginning of | |
180 // each ImageBitmap() constructor, which makes sure that doing | |
181 // width * height * bytesPerPixel will never overflow unsigned. | |
182 unsigned width = static_cast<unsigned>(input->width()); | 203 unsigned width = static_cast<unsigned>(input->width()); |
183 RefPtr<ArrayBuffer> dst_buffer = | 204 RefPtr<ArrayBuffer> dst_buffer = |
184 ArrayBuffer::CreateOrNull(width * input->height(), info.bytesPerPixel()); | 205 ArrayBuffer::CreateOrNull(width * input->height(), info.bytesPerPixel()); |
185 if (!dst_buffer) | 206 if (!dst_buffer) |
186 return nullptr; | 207 return nullptr; |
187 RefPtr<Uint8Array> dst_pixels = | 208 RefPtr<Uint8Array> dst_pixels = |
188 Uint8Array::Create(dst_buffer, 0, dst_buffer->ByteLength()); | 209 Uint8Array::Create(dst_buffer, 0, dst_buffer->ByteLength()); |
189 input->readPixels(info, dst_pixels->Data(), width * info.bytesPerPixel(), 0, | 210 input->readPixels(info, dst_pixels->Data(), width * info.bytesPerPixel(), 0, |
190 0); | 211 0); |
191 return dst_pixels; | 212 return dst_pixels; |
192 } | 213 } |
193 | 214 |
194 static sk_sp<SkImage> NewSkImageFromRaster(const SkImageInfo& info, | 215 static sk_sp<SkImage> NewSkImageFromRaster(const SkImageInfo& info, |
195 PassRefPtr<Uint8Array> image_pixels, | 216 PassRefPtr<Uint8Array> image_pixels, |
196 unsigned image_row_bytes) { | 217 unsigned image_row_bytes) { |
197 SkPixmap pixmap(info, image_pixels->Data(), image_row_bytes); | 218 SkPixmap pixmap(info, image_pixels->Data(), image_row_bytes); |
198 return SkImage::MakeFromRaster(pixmap, | 219 return SkImage::MakeFromRaster(pixmap, |
199 [](const void*, void* pixels) { | 220 [](const void*, void* pixels) { |
200 static_cast<Uint8Array*>(pixels)->Deref(); | 221 static_cast<Uint8Array*>(pixels)->Deref(); |
201 }, | 222 }, |
202 image_pixels.LeakRef()); | 223 image_pixels.LeakRef()); |
203 } | 224 } |
204 | 225 |
205 static void SwizzleImageData(unsigned char* src_addr, | |
206 unsigned height, | |
207 unsigned bytes_per_row, | |
208 bool flip_y) { | |
209 if (flip_y) { | |
210 for (unsigned i = 0; i < height / 2; i++) { | |
211 unsigned top_row_start_position = i * bytes_per_row; | |
212 unsigned bottom_row_start_position = (height - 1 - i) * bytes_per_row; | |
213 if (kN32_SkColorType == kBGRA_8888_SkColorType) { // needs to swizzle | |
214 for (unsigned j = 0; j < bytes_per_row; j += 4) { | |
215 std::swap(src_addr[top_row_start_position + j], | |
216 src_addr[bottom_row_start_position + j + 2]); | |
217 std::swap(src_addr[top_row_start_position + j + 1], | |
218 src_addr[bottom_row_start_position + j + 1]); | |
219 std::swap(src_addr[top_row_start_position + j + 2], | |
220 src_addr[bottom_row_start_position + j]); | |
221 std::swap(src_addr[top_row_start_position + j + 3], | |
222 src_addr[bottom_row_start_position + j + 3]); | |
223 } | |
224 } else { | |
225 std::swap_ranges(src_addr + top_row_start_position, | |
226 src_addr + top_row_start_position + bytes_per_row, | |
227 src_addr + bottom_row_start_position); | |
228 } | |
229 } | |
230 } else { | |
231 if (kN32_SkColorType == kBGRA_8888_SkColorType) // needs to swizzle | |
232 for (unsigned i = 0; i < height * bytes_per_row; i += 4) | |
233 std::swap(src_addr[i], src_addr[i + 2]); | |
234 } | |
235 } | |
236 | |
237 enum AlphaPremultiplyEnforcement { | 226 enum AlphaPremultiplyEnforcement { |
238 kEnforceAlphaPremultiply, | 227 kEnforceAlphaPremultiply, |
239 kDontEnforceAlphaPremultiply, | 228 kDontEnforceAlphaPremultiply, |
240 }; | 229 }; |
241 | 230 |
242 static sk_sp<SkImage> FlipSkImageVertically( | 231 static sk_sp<SkImage> FlipSkImageVertically( |
243 SkImage* input, | 232 SkImage* input, |
244 AlphaPremultiplyEnforcement premultiply_enforcement = | 233 AlphaPremultiplyEnforcement premultiply_enforcement = |
245 kDontEnforceAlphaPremultiply, | 234 kDontEnforceAlphaPremultiply, |
246 const ParsedOptions& options = DefaultOptions()) { | 235 const ParsedOptions& options = DefaultOptions()) { |
(...skipping 21 matching lines...) Expand all Loading... |
268 image_pixels->Data() + bottom_first_element); | 257 image_pixels->Data() + bottom_first_element); |
269 } | 258 } |
270 return NewSkImageFromRaster(info, std::move(image_pixels), image_row_bytes); | 259 return NewSkImageFromRaster(info, std::move(image_pixels), image_row_bytes); |
271 } | 260 } |
272 | 261 |
273 static sk_sp<SkImage> PremulSkImageToUnPremul( | 262 static sk_sp<SkImage> PremulSkImageToUnPremul( |
274 SkImage* input, | 263 SkImage* input, |
275 const ParsedOptions& options = DefaultOptions()) { | 264 const ParsedOptions& options = DefaultOptions()) { |
276 SkImageInfo info = SkImageInfo::Make( | 265 SkImageInfo info = SkImageInfo::Make( |
277 input->width(), input->height(), options.color_params.GetSkColorType(), | 266 input->width(), input->height(), options.color_params.GetSkColorType(), |
278 kUnpremul_SkAlphaType, input->refColorSpace()); | 267 kPremul_SkAlphaType, options.color_params.GetSkColorSpaceForSkSurfaces()); |
279 | 268 |
| 269 LOG(ERROR) << "Premul:"; |
| 270 std::stringstream str; |
| 271 std::unique_ptr<uint8_t[]> read_pixels(new uint8_t[64]()); |
| 272 input->readPixels(info, read_pixels.get(), input->width() * 4, 0, 0); |
| 273 for (int i = 0; i < 16; i++) { |
| 274 str << "["; |
| 275 for (int j = 0; j < 4; j++) |
| 276 str << (int)(read_pixels[i * 4 + j]) << ","; |
| 277 str << "] "; |
| 278 } |
| 279 LOG(ERROR) << str.str(); |
| 280 |
| 281 info = info.makeAlphaType(kUnpremul_SkAlphaType); |
280 RefPtr<Uint8Array> dst_pixels = CopySkImageData(input, info); | 282 RefPtr<Uint8Array> dst_pixels = CopySkImageData(input, info); |
| 283 LOG(ERROR) << "Unpremul:"; |
| 284 str.str(""); |
| 285 for (int i = 0; i < 16; i++) { |
| 286 str << "["; |
| 287 for (int j = 0; j < 4; j++) |
| 288 str << (int)(dst_pixels->Data()[i * 4 + j]) << ","; |
| 289 str << "] "; |
| 290 } |
| 291 LOG(ERROR) << str.str(); |
| 292 |
281 if (!dst_pixels) | 293 if (!dst_pixels) |
282 return nullptr; | 294 return nullptr; |
283 return NewSkImageFromRaster( | 295 return NewSkImageFromRaster( |
284 info, std::move(dst_pixels), | 296 info, std::move(dst_pixels), |
285 static_cast<unsigned>(input->width()) * info.bytesPerPixel()); | 297 static_cast<unsigned>(input->width()) * info.bytesPerPixel()); |
286 } | 298 } |
287 | 299 |
288 static sk_sp<SkImage> UnPremulSkImageToPremul( | 300 static sk_sp<SkImage> UnPremulSkImageToPremul( |
289 SkImage* input, | 301 SkImage* input, |
290 const ParsedOptions& options = DefaultOptions()) { | 302 const ParsedOptions& options = DefaultOptions()) { |
291 SkImageInfo info = SkImageInfo::Make( | 303 SkImageInfo info = SkImageInfo::Make( |
292 input->width(), input->height(), options.color_params.GetSkColorType(), | 304 input->width(), input->height(), options.color_params.GetSkColorType(), |
293 kPremul_SkAlphaType, input->refColorSpace()); | 305 kPremul_SkAlphaType, input->refColorSpace()); |
294 | 306 |
295 RefPtr<Uint8Array> dst_pixels = CopySkImageData(input, info); | 307 RefPtr<Uint8Array> dst_pixels = CopySkImageData(input, info); |
296 if (!dst_pixels) | 308 if (!dst_pixels) |
297 return nullptr; | 309 return nullptr; |
298 return NewSkImageFromRaster( | 310 return NewSkImageFromRaster( |
299 info, std::move(dst_pixels), | 311 info, std::move(dst_pixels), |
300 static_cast<unsigned>(input->width()) * info.bytesPerPixel()); | 312 static_cast<unsigned>(input->width()) * info.bytesPerPixel()); |
301 } | 313 } |
302 | 314 |
303 static void ApplyColorSpaceConversion(sk_sp<SkImage>& image, | 315 static void ApplyColorSpaceConversion(sk_sp<SkImage>& image, |
304 ParsedOptions& options) { | 316 ParsedOptions& options) { |
305 if (!options.color_canvas_extensions_enabled) | 317 if (!options.color_canvas_extensions_enabled) |
306 return; | 318 return; |
307 | 319 |
308 sk_sp<SkColorSpace> dst_color_space = nullptr; | 320 SkColorType dst_color_type = options.color_params.GetSkColorType(); |
309 SkColorType dst_color_type = kN32_SkColorType; | 321 sk_sp<SkColorSpace> dst_color_space = options.color_params.GetSkColorSpace(); |
310 dst_color_space = options.color_params.GetSkColorSpace(); | |
311 dst_color_type = options.color_params.GetSkColorType(); | |
312 if (SkColorSpace::Equals(image->colorSpace(), dst_color_space.get())) | 322 if (SkColorSpace::Equals(image->colorSpace(), dst_color_space.get())) |
313 return; | 323 return; |
314 | 324 |
315 SkImageInfo dst_info = | 325 SkImageInfo dst_info = |
316 SkImageInfo::Make(image->width(), image->height(), dst_color_type, | 326 SkImageInfo::Make(image->width(), image->height(), dst_color_type, |
317 image->alphaType(), dst_color_space); | 327 image->alphaType(), dst_color_space); |
318 | 328 |
319 size_t size = image->width() * image->height() * dst_info.bytesPerPixel(); | 329 size_t size = image->width() * image->height() * dst_info.bytesPerPixel(); |
320 sk_sp<SkData> dst_data = SkData::MakeUninitialized(size); | 330 sk_sp<SkData> dst_data = SkData::MakeUninitialized(size); |
321 if (dst_data->size() != size) | 331 if (dst_data->size() != size) |
322 return; | 332 return; |
323 sk_sp<SkImage> colored_image = nullptr; | 333 sk_sp<SkImage> colored_image = nullptr; |
| 334 // The desired way to apply color space conversion on a SkImage is to use |
| 335 // SkImage::readPixels. |
324 if (image->readPixels(dst_info, dst_data->writable_data(), | 336 if (image->readPixels(dst_info, dst_data->writable_data(), |
325 image->width() * dst_info.bytesPerPixel(), 0, 0)) { | 337 image->width() * dst_info.bytesPerPixel(), 0, 0)) { |
326 colored_image = SkImage::MakeRasterData( | 338 colored_image = SkImage::MakeRasterData( |
327 dst_info, dst_data, image->width() * dst_info.bytesPerPixel()); | 339 dst_info, dst_data, image->width() * dst_info.bytesPerPixel()); |
328 } else { | 340 } else { |
329 // The desired way to apply color space conversion on a SkImage is to use | 341 // However, if the SkImage is GPU-backed, readPixels might not work |
330 // SkImage::readPixels. However, if the SkImage is GPU-backed, readPixels | 342 // properly. In this case, we fall back to drawing the SkImage to a |
331 // still might not work properly. In this case, we fall back to drawing | 343 // canvas and reading back the result. |
332 // the SkImage to a canvas and reading back the result. | |
333 // Skia does not support drawing to unpremul surfaces/canvases. | 344 // Skia does not support drawing to unpremul surfaces/canvases. |
334 sk_sp<SkImage> un_premul_image = nullptr; | 345 sk_sp<SkImage> un_premul_image = nullptr; |
335 if (image->alphaType() == kUnpremul_SkAlphaType) { | 346 if (image->alphaType() == kUnpremul_SkAlphaType) { |
336 un_premul_image = UnPremulSkImageToPremul(image.get(), options); | 347 un_premul_image = UnPremulSkImageToPremul(image.get(), options); |
337 dst_info = dst_info.makeAlphaType(kPremul_SkAlphaType); | 348 dst_info = dst_info.makeAlphaType(kPremul_SkAlphaType); |
338 } | 349 } |
339 | 350 |
340 // If the color space of the source SkImage is null, the following code | 351 // If the color space of the source SkImage is null, the following code |
341 // does not do any color conversion. This cannot be addressed here and | 352 // does not do any color conversion. This cannot be addressed here and |
342 // the code that creates the SkImage must tag the SkImage with proper | 353 // the code that creates the SkImage must tag the SkImage with proper |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 // need to use the ImageDecoder to decode the image. | 415 // need to use the ImageDecoder to decode the image. |
405 static PassRefPtr<StaticBitmapImage> CropImageAndApplyColorSpaceConversion( | 416 static PassRefPtr<StaticBitmapImage> CropImageAndApplyColorSpaceConversion( |
406 Image* image, | 417 Image* image, |
407 ParsedOptions& parsed_options, | 418 ParsedOptions& parsed_options, |
408 AlphaDisposition image_format, | 419 AlphaDisposition image_format, |
409 ColorBehavior color_behavior) { | 420 ColorBehavior color_behavior) { |
410 DCHECK(image); | 421 DCHECK(image); |
411 IntRect img_rect(IntPoint(), IntSize(image->width(), image->height())); | 422 IntRect img_rect(IntPoint(), IntSize(image->width(), image->height())); |
412 const IntRect src_rect = Intersection(img_rect, parsed_options.crop_rect); | 423 const IntRect src_rect = Intersection(img_rect, parsed_options.crop_rect); |
413 | 424 |
414 // In the case when cropRect doesn't intersect the source image and it | 425 // In the case when cropRect doesn't intersect the source image, we |
415 // requires a umpremul image We immediately return a transparent black image | 426 // return a transparent black image, respecting the color_params but |
416 // with cropRect.size() | 427 // ignoring premultiply_alpha. |
417 if (src_rect.IsEmpty() && !parsed_options.premultiply_alpha) { | 428 if (src_rect.IsEmpty()) { |
418 SkImageInfo info = SkImageInfo::Make( | 429 SkImageInfo info = SkImageInfo::Make( |
419 parsed_options.resize_width, parsed_options.resize_height, | 430 parsed_options.crop_rect.Width(), parsed_options.crop_rect.Height(), |
420 kN32_SkColorType, kUnpremul_SkAlphaType); | 431 parsed_options.color_params.GetSkColorType(), kPremul_SkAlphaType, |
421 RefPtr<ArrayBuffer> dst_buffer = ArrayBuffer::CreateOrNull( | 432 parsed_options.color_params.GetSkColorSpace()); |
422 static_cast<unsigned>(info.width()) * info.height(), | 433 if (parsed_options.should_scale_input) { |
423 info.bytesPerPixel()); | 434 info = info.makeWH(parsed_options.resize_width, |
424 if (!dst_buffer) | 435 parsed_options.resize_height); |
| 436 } |
| 437 sk_sp<SkSurface> surface = SkSurface::MakeRaster(info); |
| 438 if (!surface) |
425 return nullptr; | 439 return nullptr; |
426 RefPtr<Uint8Array> dst_pixels = | 440 return StaticBitmapImage::Create(surface->makeImageSnapshot()); |
427 Uint8Array::Create(dst_buffer, 0, dst_buffer->ByteLength()); | |
428 return StaticBitmapImage::Create(NewSkImageFromRaster( | |
429 info, std::move(dst_pixels), | |
430 static_cast<unsigned>(info.width()) * info.bytesPerPixel())); | |
431 } | 441 } |
432 | 442 |
433 sk_sp<SkImage> skia_image = image->ImageForCurrentFrame(); | 443 sk_sp<SkImage> skia_image = image->ImageForCurrentFrame(); |
434 // Attempt to get raw unpremultiplied image data, executed only when skiaImage | 444 // Attempt to get raw unpremultiplied image data, executed only when |
435 // is premultiplied. | 445 // skia_image is premultiplied. |
436 if ((((!parsed_options.premultiply_alpha && !skia_image->isOpaque()) || | 446 if ((((!parsed_options.premultiply_alpha && !skia_image->isOpaque()) || |
437 !skia_image) && | 447 !skia_image) && |
438 image->Data() && image_format == kPremultiplyAlpha) || | 448 image->Data() && image_format == kPremultiplyAlpha) || |
439 color_behavior.IsIgnore()) { | 449 color_behavior.IsIgnore()) { |
| 450 LOG(ERROR) << "HERE..."; |
440 std::unique_ptr<ImageDecoder> decoder(ImageDecoder::Create( | 451 std::unique_ptr<ImageDecoder> decoder(ImageDecoder::Create( |
441 image->Data(), true, | 452 image->Data(), true, |
442 parsed_options.premultiply_alpha ? ImageDecoder::kAlphaPremultiplied | 453 parsed_options.premultiply_alpha ? ImageDecoder::kAlphaPremultiplied |
443 : ImageDecoder::kAlphaNotPremultiplied, | 454 : ImageDecoder::kAlphaNotPremultiplied, |
444 color_behavior)); | 455 color_behavior)); |
445 if (!decoder) | 456 if (!decoder) |
446 return nullptr; | 457 return nullptr; |
447 SkColorType color_type = parsed_options.color_params.GetSkColorType(); | 458 SkColorType color_type = parsed_options.color_params.GetSkColorType(); |
448 sk_sp<SkColorSpace> color_space = | 459 sk_sp<SkColorSpace> color_space = |
449 parsed_options.color_params.GetSkColorSpace(); | 460 parsed_options.color_params.GetSkColorSpace(); |
450 skia_image = ImageBitmap::GetSkImageFromDecoder( | 461 skia_image = ImageBitmap::GetSkImageFromDecoder( |
451 std::move(decoder), &color_type, &color_space, | 462 std::move(decoder), &color_type, &color_space, |
452 kUpdateColorSpaceInformation); | 463 kUpdateColorSpaceInformation); |
453 if (!skia_image) | 464 if (!skia_image) |
454 return nullptr; | 465 return nullptr; |
455 } | 466 } |
456 | 467 |
457 if (parsed_options.crop_rect == src_rect && | 468 if (!parsed_options.should_scale_input) { |
458 !parsed_options.should_scale_input) { | |
459 sk_sp<SkImage> cropped_sk_image = skia_image->makeSubset(src_rect); | 469 sk_sp<SkImage> cropped_sk_image = skia_image->makeSubset(src_rect); |
460 ApplyColorSpaceConversion(cropped_sk_image, parsed_options); | 470 ApplyColorSpaceConversion(cropped_sk_image, parsed_options); |
461 if (parsed_options.flip_y) { | 471 if (parsed_options.flip_y) { |
462 return StaticBitmapImage::Create( | 472 return StaticBitmapImage::Create( |
463 FlipSkImageVertically(cropped_sk_image.get(), | 473 FlipSkImageVertically(cropped_sk_image.get(), |
464 kDontEnforceAlphaPremultiply, parsed_options)); | 474 kDontEnforceAlphaPremultiply, parsed_options)); |
465 } | 475 } |
466 // Special case: The first parameter image is unpremul but we need to turn | 476 // Special case: The first parameter image is unpremul but we need to turn |
467 // it into premul. | 477 // it into premul. |
468 if (parsed_options.premultiply_alpha && | 478 if (parsed_options.premultiply_alpha && |
469 image_format == kDontPremultiplyAlpha) { | 479 image_format == kDontPremultiplyAlpha) { |
470 return StaticBitmapImage::Create( | 480 return StaticBitmapImage::Create( |
471 UnPremulSkImageToPremul(cropped_sk_image.get())); | 481 UnPremulSkImageToPremul(cropped_sk_image.get())); |
472 } | 482 } |
473 return StaticBitmapImage::Create(std::move(cropped_sk_image)); | 483 return StaticBitmapImage::Create(std::move(cropped_sk_image)); |
474 } | 484 } |
475 | 485 |
476 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul( | 486 LOG(ERROR) << "HERE..."; |
477 parsed_options.resize_width, parsed_options.resize_height); | 487 SkImageInfo info = SkImageInfo::Make( |
| 488 parsed_options.resize_width, parsed_options.resize_height, |
| 489 parsed_options.color_params.GetSkColorType(), |
| 490 parsed_options.premultiply_alpha ? kPremul_SkAlphaType |
| 491 : kUnpremul_SkAlphaType, |
| 492 parsed_options.color_params.GetSkColorSpace()); |
| 493 sk_sp<SkSurface> surface = SkSurface::MakeRaster(info); |
478 if (!surface) | 494 if (!surface) |
479 return nullptr; | 495 return nullptr; |
480 if (src_rect.IsEmpty()) | |
481 return StaticBitmapImage::Create(surface->makeImageSnapshot()); | |
482 | |
483 SkScalar dst_left = std::min(0, -parsed_options.crop_rect.X()); | |
484 SkScalar dst_top = std::min(0, -parsed_options.crop_rect.Y()); | |
485 if (parsed_options.crop_rect.X() < 0) | |
486 dst_left = -parsed_options.crop_rect.X(); | |
487 if (parsed_options.crop_rect.Y() < 0) | |
488 dst_top = -parsed_options.crop_rect.Y(); | |
489 if (parsed_options.flip_y) { | 496 if (parsed_options.flip_y) { |
490 surface->getCanvas()->translate(0, surface->height()); | 497 surface->getCanvas()->translate(0, surface->height()); |
491 surface->getCanvas()->scale(1, -1); | 498 surface->getCanvas()->scale(1, -1); |
492 } | 499 } |
493 if (parsed_options.should_scale_input) { | 500 |
494 SkRect draw_src_rect = SkRect::MakeXYWH( | 501 SkRect draw_src_rect(parsed_options.crop_rect); |
495 parsed_options.crop_rect.X(), parsed_options.crop_rect.Y(), | 502 SkRect draw_dst_rect = |
496 parsed_options.crop_rect.Width(), parsed_options.crop_rect.Height()); | 503 SkRect::MakeWH(parsed_options.resize_width, parsed_options.resize_height); |
497 SkRect draw_dst_rect = SkRect::MakeXYWH(0, 0, parsed_options.resize_width, | 504 SkPaint paint; |
498 parsed_options.resize_height); | 505 paint.setFilterQuality(parsed_options.resize_quality); |
499 SkPaint paint; | 506 surface->getCanvas()->drawImageRect(skia_image, draw_src_rect, draw_dst_rect, |
500 paint.setFilterQuality(parsed_options.resize_quality); | 507 &paint); |
501 surface->getCanvas()->drawImageRect(skia_image, draw_src_rect, | 508 |
502 draw_dst_rect, &paint); | |
503 } else { | |
504 surface->getCanvas()->drawImage(skia_image, dst_left, dst_top); | |
505 } | |
506 skia_image = surface->makeImageSnapshot(); | 509 skia_image = surface->makeImageSnapshot(); |
| 510 PrintSkImage(skia_image); |
507 ApplyColorSpaceConversion(skia_image, parsed_options); | 511 ApplyColorSpaceConversion(skia_image, parsed_options); |
| 512 PrintSkImage(skia_image); |
508 | 513 |
509 if (parsed_options.premultiply_alpha) { | 514 if (parsed_options.premultiply_alpha) { |
| 515 LOG(ERROR) << "HERE"; |
510 if (image_format == kDontPremultiplyAlpha) | 516 if (image_format == kDontPremultiplyAlpha) |
511 return StaticBitmapImage::Create( | 517 return StaticBitmapImage::Create( |
512 UnPremulSkImageToPremul(skia_image.get())); | 518 UnPremulSkImageToPremul(skia_image.get())); |
513 return StaticBitmapImage::Create(std::move(skia_image)); | 519 return StaticBitmapImage::Create(std::move(skia_image)); |
514 } | 520 } |
515 return StaticBitmapImage::Create(PremulSkImageToUnPremul(skia_image.get())); | 521 LOG(ERROR) << "HERE"; |
| 522 return StaticBitmapImage::Create(std::move(skia_image)); |
| 523 // return StaticBitmapImage::Create( |
| 524 // PremulSkImageToUnPremul(skia_image.get(), parsed_options)); |
516 } | 525 } |
517 | 526 |
518 ImageBitmap::ImageBitmap(ImageElementBase* image, | 527 ImageBitmap::ImageBitmap(ImageElementBase* image, |
519 Optional<IntRect> crop_rect, | 528 Optional<IntRect> crop_rect, |
520 Document* document, | 529 Document* document, |
521 const ImageBitmapOptions& options) { | 530 const ImageBitmapOptions& options) { |
| 531 LOG(ERROR) << "Entering..."; |
522 RefPtr<Image> input = image->CachedImage()->GetImage(); | 532 RefPtr<Image> input = image->CachedImage()->GetImage(); |
523 ParsedOptions parsed_options = | 533 ParsedOptions parsed_options = |
524 ParseOptions(options, crop_rect, image->BitmapSourceSize()); | 534 ParseOptions(options, crop_rect, image->BitmapSourceSize()); |
525 if (DstBufferSizeHasOverflow(parsed_options)) | 535 if (DstBufferSizeHasOverflow(parsed_options)) |
526 return; | 536 return; |
527 | 537 |
528 if (options.colorSpaceConversion() == kImageBitmapOptionNone) { | 538 if (options.colorSpaceConversion() == kImageBitmapOptionNone) { |
529 image_ = CropImageAndApplyColorSpaceConversion(input.Get(), parsed_options, | 539 image_ = CropImageAndApplyColorSpaceConversion(input.Get(), parsed_options, |
530 kPremultiplyAlpha, | 540 kPremultiplyAlpha, |
531 ColorBehavior::Ignore()); | 541 ColorBehavior::Ignore()); |
(...skipping 27 matching lines...) Expand all Loading... |
559 return; | 569 return; |
560 image_->SetOriginClean( | 570 image_->SetOriginClean( |
561 !image->WouldTaintOrigin(document->GetSecurityOrigin())); | 571 !image->WouldTaintOrigin(document->GetSecurityOrigin())); |
562 image_->SetPremultiplied(parsed_options.premultiply_alpha); | 572 image_->SetPremultiplied(parsed_options.premultiply_alpha); |
563 } | 573 } |
564 | 574 |
565 ImageBitmap::ImageBitmap(HTMLVideoElement* video, | 575 ImageBitmap::ImageBitmap(HTMLVideoElement* video, |
566 Optional<IntRect> crop_rect, | 576 Optional<IntRect> crop_rect, |
567 Document* document, | 577 Document* document, |
568 const ImageBitmapOptions& options) { | 578 const ImageBitmapOptions& options) { |
| 579 LOG(ERROR) << "Entering..."; |
569 IntSize player_size; | 580 IntSize player_size; |
570 if (video->GetWebMediaPlayer()) | 581 if (video->GetWebMediaPlayer()) |
571 player_size = video->GetWebMediaPlayer()->NaturalSize(); | 582 player_size = video->GetWebMediaPlayer()->NaturalSize(); |
572 ParsedOptions parsed_options = | 583 ParsedOptions parsed_options = |
573 ParseOptions(options, crop_rect, video->BitmapSourceSize()); | 584 ParseOptions(options, crop_rect, video->BitmapSourceSize()); |
574 if (DstBufferSizeHasOverflow(parsed_options)) | 585 if (DstBufferSizeHasOverflow(parsed_options)) |
575 return; | 586 return; |
576 | 587 |
577 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::Create( | 588 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::Create( |
578 IntSize(parsed_options.resize_width, parsed_options.resize_height), | 589 IntSize(parsed_options.resize_width, parsed_options.resize_height), |
(...skipping 18 matching lines...) Expand all Loading... |
597 } | 608 } |
598 buffer->Canvas()->translate(dst_point.X(), dst_point.Y()); | 609 buffer->Canvas()->translate(dst_point.X(), dst_point.Y()); |
599 video->PaintCurrentFrame( | 610 video->PaintCurrentFrame( |
600 buffer->Canvas(), | 611 buffer->Canvas(), |
601 IntRect(IntPoint(), IntSize(video->videoWidth(), video->videoHeight())), | 612 IntRect(IntPoint(), IntSize(video->videoWidth(), video->videoHeight())), |
602 parsed_options.should_scale_input ? &flags : nullptr); | 613 parsed_options.should_scale_input ? &flags : nullptr); |
603 | 614 |
604 sk_sp<SkImage> skia_image = | 615 sk_sp<SkImage> skia_image = |
605 buffer->NewSkImageSnapshot(kPreferNoAcceleration, kSnapshotReasonUnknown); | 616 buffer->NewSkImageSnapshot(kPreferNoAcceleration, kSnapshotReasonUnknown); |
606 if (!parsed_options.premultiply_alpha) | 617 if (!parsed_options.premultiply_alpha) |
607 skia_image = PremulSkImageToUnPremul(skia_image.get()); | 618 skia_image = PremulSkImageToUnPremul(skia_image.get(), parsed_options); |
608 if (!skia_image) | 619 if (!skia_image) |
609 return; | 620 return; |
610 image_ = StaticBitmapImage::Create(std::move(skia_image)); | 621 image_ = StaticBitmapImage::Create(std::move(skia_image)); |
611 image_->SetOriginClean( | 622 image_->SetOriginClean( |
612 !video->WouldTaintOrigin(document->GetSecurityOrigin())); | 623 !video->WouldTaintOrigin(document->GetSecurityOrigin())); |
613 image_->SetPremultiplied(parsed_options.premultiply_alpha); | 624 image_->SetPremultiplied(parsed_options.premultiply_alpha); |
614 } | 625 } |
615 | 626 |
616 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, | 627 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, |
617 Optional<IntRect> crop_rect, | 628 Optional<IntRect> crop_rect, |
618 const ImageBitmapOptions& options) { | 629 const ImageBitmapOptions& options) { |
| 630 LOG(ERROR) << "Entering..."; |
619 DCHECK(canvas->IsPaintable()); | 631 DCHECK(canvas->IsPaintable()); |
620 RefPtr<Image> input; | 632 RefPtr<Image> input; |
621 if (canvas->PlaceholderFrame()) { | 633 if (canvas->PlaceholderFrame()) { |
622 input = canvas->PlaceholderFrame(); | 634 input = canvas->PlaceholderFrame(); |
623 } else { | 635 } else { |
624 input = canvas->CopiedImage(kBackBuffer, kPreferAcceleration, | 636 input = canvas->CopiedImage(kBackBuffer, kPreferAcceleration, |
625 kSnapshotReasonCreateImageBitmap); | 637 kSnapshotReasonCreateImageBitmap); |
626 } | 638 } |
627 ParsedOptions parsed_options = ParseOptions( | 639 ParsedOptions parsed_options = ParseOptions( |
628 options, crop_rect, IntSize(input->width(), input->height())); | 640 options, crop_rect, IntSize(input->width(), input->height())); |
629 if (DstBufferSizeHasOverflow(parsed_options)) | 641 if (DstBufferSizeHasOverflow(parsed_options)) |
630 return; | 642 return; |
631 | 643 |
632 bool is_premultiply_alpha_reverted = false; | 644 bool is_premultiply_alpha_reverted = false; |
633 if (!parsed_options.premultiply_alpha) { | 645 if (!parsed_options.premultiply_alpha) { |
634 parsed_options.premultiply_alpha = true; | 646 parsed_options.premultiply_alpha = true; |
635 is_premultiply_alpha_reverted = true; | 647 is_premultiply_alpha_reverted = true; |
636 } | 648 } |
637 image_ = CropImageAndApplyColorSpaceConversion( | 649 image_ = CropImageAndApplyColorSpaceConversion( |
638 input.Get(), parsed_options, kPremultiplyAlpha, | 650 input.Get(), parsed_options, kPremultiplyAlpha, |
639 ColorBehavior::TransformToGlobalTarget()); | 651 ColorBehavior::TransformToGlobalTarget()); |
640 if (!image_) | 652 if (!image_) |
641 return; | 653 return; |
642 if (is_premultiply_alpha_reverted) { | 654 if (is_premultiply_alpha_reverted) { |
643 parsed_options.premultiply_alpha = false; | 655 parsed_options.premultiply_alpha = false; |
644 image_ = StaticBitmapImage::Create( | 656 image_ = StaticBitmapImage::Create(PremulSkImageToUnPremul( |
645 PremulSkImageToUnPremul(image_->ImageForCurrentFrame().get())); | 657 image_->ImageForCurrentFrame().get(), parsed_options)); |
646 } | 658 } |
647 if (!image_) | 659 if (!image_) |
648 return; | 660 return; |
649 image_->SetOriginClean(canvas->OriginClean()); | 661 image_->SetOriginClean(canvas->OriginClean()); |
650 image_->SetPremultiplied(parsed_options.premultiply_alpha); | 662 image_->SetPremultiplied(parsed_options.premultiply_alpha); |
651 } | 663 } |
652 | 664 |
653 ImageBitmap::ImageBitmap(OffscreenCanvas* offscreen_canvas, | 665 ImageBitmap::ImageBitmap(OffscreenCanvas* offscreen_canvas, |
654 Optional<IntRect> crop_rect, | 666 Optional<IntRect> crop_rect, |
655 const ImageBitmapOptions& options) { | 667 const ImageBitmapOptions& options) { |
| 668 LOG(ERROR) << "Entering..."; |
656 SourceImageStatus status; | 669 SourceImageStatus status; |
657 RefPtr<Image> input = offscreen_canvas->GetSourceImageForCanvas( | 670 RefPtr<Image> input = offscreen_canvas->GetSourceImageForCanvas( |
658 &status, kPreferNoAcceleration, kSnapshotReasonCreateImageBitmap, | 671 &status, kPreferNoAcceleration, kSnapshotReasonCreateImageBitmap, |
659 FloatSize(offscreen_canvas->Size())); | 672 FloatSize(offscreen_canvas->Size())); |
660 if (status != kNormalSourceImageStatus) | 673 if (status != kNormalSourceImageStatus) |
661 return; | 674 return; |
662 ParsedOptions parsed_options = ParseOptions( | 675 ParsedOptions parsed_options = ParseOptions( |
663 options, crop_rect, IntSize(input->width(), input->height())); | 676 options, crop_rect, IntSize(input->width(), input->height())); |
664 if (DstBufferSizeHasOverflow(parsed_options)) | 677 if (DstBufferSizeHasOverflow(parsed_options)) |
665 return; | 678 return; |
666 | 679 |
667 bool is_premultiply_alpha_reverted = false; | 680 bool is_premultiply_alpha_reverted = false; |
668 if (!parsed_options.premultiply_alpha) { | 681 if (!parsed_options.premultiply_alpha) { |
669 parsed_options.premultiply_alpha = true; | 682 parsed_options.premultiply_alpha = true; |
670 is_premultiply_alpha_reverted = true; | 683 is_premultiply_alpha_reverted = true; |
671 } | 684 } |
672 image_ = CropImageAndApplyColorSpaceConversion( | 685 image_ = CropImageAndApplyColorSpaceConversion( |
673 input.Get(), parsed_options, kPremultiplyAlpha, | 686 input.Get(), parsed_options, kPremultiplyAlpha, |
674 ColorBehavior::TransformToGlobalTarget()); | 687 ColorBehavior::TransformToGlobalTarget()); |
675 if (!image_) | 688 if (!image_) |
676 return; | 689 return; |
677 if (is_premultiply_alpha_reverted) { | 690 if (is_premultiply_alpha_reverted) { |
678 parsed_options.premultiply_alpha = false; | 691 parsed_options.premultiply_alpha = false; |
679 image_ = StaticBitmapImage::Create( | 692 image_ = StaticBitmapImage::Create(PremulSkImageToUnPremul( |
680 PremulSkImageToUnPremul(image_->ImageForCurrentFrame().get())); | 693 image_->ImageForCurrentFrame().get(), parsed_options)); |
681 } | 694 } |
682 if (!image_) | 695 if (!image_) |
683 return; | 696 return; |
684 image_->SetOriginClean(offscreen_canvas->OriginClean()); | 697 image_->SetOriginClean(offscreen_canvas->OriginClean()); |
685 image_->SetPremultiplied(parsed_options.premultiply_alpha); | 698 image_->SetPremultiplied(parsed_options.premultiply_alpha); |
686 } | 699 } |
687 | 700 |
688 ImageBitmap::ImageBitmap(const void* pixel_data, | 701 ImageBitmap::ImageBitmap(const void* pixel_data, |
689 uint32_t width, | 702 uint32_t width, |
690 uint32_t height, | 703 uint32_t height, |
691 bool is_image_bitmap_premultiplied, | 704 bool is_image_bitmap_premultiplied, |
692 bool is_image_bitmap_origin_clean) { | 705 bool is_image_bitmap_origin_clean) { |
| 706 LOG(ERROR) << "Entering..."; |
693 SkImageInfo info = SkImageInfo::MakeN32(width, height, | 707 SkImageInfo info = SkImageInfo::MakeN32(width, height, |
694 is_image_bitmap_premultiplied | 708 is_image_bitmap_premultiplied |
695 ? kPremul_SkAlphaType | 709 ? kPremul_SkAlphaType |
696 : kUnpremul_SkAlphaType); | 710 : kUnpremul_SkAlphaType); |
697 SkPixmap pixmap(info, pixel_data, info.bytesPerPixel() * width); | 711 SkPixmap pixmap(info, pixel_data, info.bytesPerPixel() * width); |
698 image_ = StaticBitmapImage::Create(SkImage::MakeRasterCopy(pixmap)); | 712 image_ = StaticBitmapImage::Create(SkImage::MakeRasterCopy(pixmap)); |
699 if (!image_) | 713 if (!image_) |
700 return; | 714 return; |
701 image_->SetPremultiplied(is_image_bitmap_premultiplied); | 715 image_->SetPremultiplied(is_image_bitmap_premultiplied); |
702 image_->SetOriginClean(is_image_bitmap_origin_clean); | 716 image_->SetOriginClean(is_image_bitmap_origin_clean); |
703 } | 717 } |
704 | 718 |
705 static sk_sp<SkImage> ScaleSkImage(sk_sp<SkImage> sk_image, | 719 static sk_sp<SkImage> ScaleSkImage(sk_sp<SkImage> sk_image, |
| 720 const SkImageInfo& sk_image_info, |
706 unsigned resize_width, | 721 unsigned resize_width, |
707 unsigned resize_height, | 722 unsigned resize_height, |
708 SkFilterQuality resize_quality, | 723 SkFilterQuality resize_quality) { |
709 SkColorType color_type = kN32_SkColorType, | 724 SkImageInfo resized_info = sk_image_info.makeWH(resize_width, resize_height); |
710 sk_sp<SkColorSpace> color_space = nullptr) { | |
711 SkImageInfo resized_info = | |
712 SkImageInfo::Make(resize_width, resize_height, color_type, | |
713 kUnpremul_SkAlphaType, color_space); | |
714 RefPtr<ArrayBuffer> dst_buffer = ArrayBuffer::CreateOrNull( | 725 RefPtr<ArrayBuffer> dst_buffer = ArrayBuffer::CreateOrNull( |
715 resize_width * resize_height, resized_info.bytesPerPixel()); | 726 resize_width * resize_height, resized_info.bytesPerPixel()); |
716 if (!dst_buffer) | 727 if (!dst_buffer) |
717 return nullptr; | 728 return nullptr; |
718 | 729 |
719 if (color_type == kN32_SkColorType) { | 730 RefPtr<Uint8Array> resized_pixels = |
720 RefPtr<Uint8Array> resized_pixels = | 731 Uint8Array::Create(dst_buffer, 0, dst_buffer->ByteLength()); |
721 Uint8Array::Create(dst_buffer, 0, dst_buffer->ByteLength()); | |
722 SkPixmap pixmap( | |
723 resized_info, resized_pixels->Data(), | |
724 static_cast<unsigned>(resize_width) * resized_info.bytesPerPixel()); | |
725 sk_image->scalePixels(pixmap, resize_quality); | |
726 return SkImage::MakeFromRaster(pixmap, | |
727 [](const void*, void* pixels) { | |
728 static_cast<Uint8Array*>(pixels)->Deref(); | |
729 }, | |
730 resized_pixels.LeakRef()); | |
731 } | |
732 | |
733 RefPtr<Float32Array> resized_pixels = | |
734 Float32Array::Create(dst_buffer, 0, dst_buffer->ByteLength()); | |
735 SkPixmap pixmap( | 732 SkPixmap pixmap( |
736 resized_info, resized_pixels->Data(), | 733 resized_info, resized_pixels->Data(), |
737 static_cast<unsigned>(resize_width) * resized_info.bytesPerPixel()); | 734 static_cast<unsigned>(resize_width) * resized_info.bytesPerPixel()); |
738 sk_image->scalePixels(pixmap, resize_quality); | 735 sk_image->scalePixels(pixmap, resize_quality); |
739 return SkImage::MakeFromRaster(pixmap, | 736 return SkImage::MakeFromRaster(pixmap, |
740 [](const void*, void* pixels) { | 737 [](const void*, void* pixels) { |
741 static_cast<Float32Array*>(pixels)->Deref(); | 738 static_cast<Uint8Array*>(pixels)->Deref(); |
742 }, | 739 }, |
743 resized_pixels.LeakRef()); | 740 resized_pixels.LeakRef()); |
744 } | 741 } |
745 | 742 |
| 743 static void SwizzleImageData(ImageData* data, bool needs_swizzle) { |
| 744 needs_swizzle = false; |
| 745 if (data && needs_swizzle) { |
| 746 SkSwapRB(reinterpret_cast<uint32_t*>(data->data()->Data()), |
| 747 reinterpret_cast<uint32_t*>(data->data()->Data()), |
| 748 data->Size().Height() * data->Size().Width()); |
| 749 } |
| 750 } |
| 751 |
746 ImageBitmap::ImageBitmap(ImageData* data, | 752 ImageBitmap::ImageBitmap(ImageData* data, |
747 Optional<IntRect> crop_rect, | 753 Optional<IntRect> crop_rect, |
748 const ImageBitmapOptions& options) { | 754 const ImageBitmapOptions& options) { |
749 // TODO(xidachen): implement the resize option | 755 LOG(ERROR) << "Entering..."; |
750 IntRect data_src_rect = IntRect(IntPoint(), data->Size()); | |
751 ParsedOptions parsed_options = | 756 ParsedOptions parsed_options = |
752 ParseOptions(options, crop_rect, data->BitmapSourceSize()); | 757 ParseOptions(options, crop_rect, data->BitmapSourceSize()); |
753 if (DstBufferSizeHasOverflow(parsed_options)) | 758 if (DstBufferSizeHasOverflow(parsed_options)) |
754 return; | 759 return; |
| 760 |
| 761 IntRect data_src_rect = IntRect(IntPoint(), data->Size()); |
755 IntRect src_rect = crop_rect | 762 IntRect src_rect = crop_rect |
756 ? Intersection(parsed_options.crop_rect, data_src_rect) | 763 ? Intersection(parsed_options.crop_rect, data_src_rect) |
757 : data_src_rect; | 764 : data_src_rect; |
| 765 SkImageInfo unpremul_info = SkImageInfo::Make( |
| 766 src_rect.Width(), src_rect.Height(), |
| 767 parsed_options.color_params.GetSkColorType(), kUnpremul_SkAlphaType, |
| 768 parsed_options.color_params.GetSkColorSpaceForSkSurfaces()); |
| 769 // if src_rect is empty, create an empty image bitmap with the requested size |
| 770 // and return |
| 771 if (src_rect.IsEmpty()) { |
| 772 SkImageInfo info = parsed_options.premultiply_alpha |
| 773 ? unpremul_info.makeAlphaType(kPremul_SkAlphaType) |
| 774 : unpremul_info; |
| 775 if (parsed_options.should_scale_input) { |
| 776 info = info.makeWH(parsed_options.resize_width, |
| 777 parsed_options.resize_height); |
| 778 } else if (crop_rect) { |
| 779 info = info.makeWH(crop_rect->Width(), crop_rect->Height()); |
| 780 } else { |
| 781 info = info.makeWH(data->Size().Width(), data->Size().Height()); |
| 782 } |
| 783 unsigned bytes_per_row = |
| 784 info.width() * parsed_options.color_params.BytesPerPixel(); |
| 785 std::unique_ptr<uint8_t[]> pixels( |
| 786 new uint8_t[info.height() * bytes_per_row]); |
| 787 memset(pixels.get(), 0, info.height() * bytes_per_row); |
| 788 sk_sp<SkImage> sk_image = |
| 789 SkImage::MakeRasterCopy(SkPixmap(info, pixels.get(), bytes_per_row)); |
| 790 image_ = StaticBitmapImage::Create(sk_image); |
| 791 image_->SetPremultiplied(parsed_options.premultiply_alpha); |
| 792 return; |
| 793 } |
| 794 |
| 795 // crop/flip the input and swizzle if needed. we swizzle back later if the |
| 796 // input ImageData is swizzled here. |
| 797 bool crop_or_flip = (src_rect != data_src_rect) || parsed_options.flip_y; |
| 798 bool needs_swizzle = |
| 799 parsed_options.color_params.GetSkColorType() == kBGRA_8888_SkColorType; |
| 800 ImageData* cropped_data = data; |
| 801 if (crop_or_flip) |
| 802 cropped_data = data->CropRect(src_rect, parsed_options.flip_y); |
| 803 SwizzleImageData(cropped_data, needs_swizzle); |
| 804 unsigned bytes_per_row = |
| 805 src_rect.Size().Width() * parsed_options.color_params.BytesPerPixel(); |
| 806 unsigned data_size = src_rect.Size().Height() * bytes_per_row; |
| 807 // color convert the pixels if needed |
| 808 unsigned char* color_corrected_pixels = cropped_data->data()->Data(); |
| 809 std::unique_ptr<uint8_t[]>* converted_pixels = nullptr; |
| 810 if (!SkColorSpace::Equals( |
| 811 cropped_data->GetCanvasColorParams() |
| 812 .GetSkColorSpaceForSkSurfaces() |
| 813 .get(), |
| 814 parsed_options.color_params.GetSkColorSpaceForSkSurfaces().get()) || |
| 815 cropped_data->GetCanvasColorParams().GetSkColorType() == |
| 816 kRGBA_F16_SkColorType) { |
| 817 converted_pixels = new std::unique_ptr<uint8_t[]>(new uint8_t[data_size]); |
| 818 cropped_data->ImageDataInCanvasColorSettings(parsed_options.color_params, |
| 819 *converted_pixels); |
| 820 color_corrected_pixels = converted_pixels->get(); |
| 821 } |
758 | 822 |
759 // treat non-premultiplyAlpha as a special case | 823 // treat non-premultiplyAlpha as a special case |
760 if (!parsed_options.premultiply_alpha) { | 824 if (!parsed_options.premultiply_alpha) { |
761 unsigned char* src_addr = data->data()->Data(); | 825 SkImageInfo info = unpremul_info.makeColorType(kRGBA_8888_SkColorType); |
| 826 sk_sp<SkImage> sk_image = SkImage::MakeRasterCopy( |
| 827 SkPixmap(info, color_corrected_pixels, bytes_per_row)); |
762 | 828 |
763 // Using kN32 type, swizzle input if necessary. | |
764 SkImageInfo info = SkImageInfo::Make( | |
765 parsed_options.crop_rect.Width(), parsed_options.crop_rect.Height(), | |
766 kN32_SkColorType, kUnpremul_SkAlphaType, data->GetSkColorSpace()); | |
767 unsigned bytes_per_pixel = static_cast<unsigned>(info.bytesPerPixel()); | |
768 unsigned src_pixel_bytes_per_row = bytes_per_pixel * data->Size().Width(); | |
769 unsigned dst_pixel_bytes_per_row = | |
770 bytes_per_pixel * parsed_options.crop_rect.Width(); | |
771 sk_sp<SkImage> sk_image; | |
772 if (parsed_options.crop_rect == IntRect(IntPoint(), data->Size())) { | |
773 SwizzleImageData(src_addr, data->Size().Height(), src_pixel_bytes_per_row, | |
774 parsed_options.flip_y); | |
775 sk_image = SkImage::MakeRasterCopy( | |
776 SkPixmap(info, src_addr, dst_pixel_bytes_per_row)); | |
777 // restore the original ImageData | |
778 SwizzleImageData(src_addr, data->Size().Height(), src_pixel_bytes_per_row, | |
779 parsed_options.flip_y); | |
780 } else { | |
781 RefPtr<ArrayBuffer> dst_buffer = ArrayBuffer::CreateOrNull( | |
782 static_cast<unsigned>(parsed_options.crop_rect.Height()) * | |
783 parsed_options.crop_rect.Width(), | |
784 bytes_per_pixel); | |
785 if (!dst_buffer) | |
786 return; | |
787 RefPtr<Uint8Array> copied_data_buffer = | |
788 Uint8Array::Create(dst_buffer, 0, dst_buffer->ByteLength()); | |
789 if (!src_rect.IsEmpty()) { | |
790 IntPoint src_point = IntPoint( | |
791 (parsed_options.crop_rect.X() > 0) ? parsed_options.crop_rect.X() | |
792 : 0, | |
793 (parsed_options.crop_rect.Y() > 0) ? parsed_options.crop_rect.Y() | |
794 : 0); | |
795 IntPoint dst_point = IntPoint((parsed_options.crop_rect.X() >= 0) | |
796 ? 0 | |
797 : -parsed_options.crop_rect.X(), | |
798 (parsed_options.crop_rect.Y() >= 0) | |
799 ? 0 | |
800 : -parsed_options.crop_rect.Y()); | |
801 int copy_height = data->Size().Height() - src_point.Y(); | |
802 if (parsed_options.crop_rect.Height() < copy_height) | |
803 copy_height = parsed_options.crop_rect.Height(); | |
804 int copy_width = data->Size().Width() - src_point.X(); | |
805 if (parsed_options.crop_rect.Width() < copy_width) | |
806 copy_width = parsed_options.crop_rect.Width(); | |
807 for (int i = 0; i < copy_height; i++) { | |
808 unsigned src_start_copy_position = | |
809 (i + src_point.Y()) * src_pixel_bytes_per_row + | |
810 src_point.X() * bytes_per_pixel; | |
811 unsigned src_end_copy_position = | |
812 src_start_copy_position + copy_width * bytes_per_pixel; | |
813 unsigned dst_start_copy_position; | |
814 if (parsed_options.flip_y) | |
815 dst_start_copy_position = | |
816 (parsed_options.crop_rect.Height() - 1 - dst_point.Y() - i) * | |
817 dst_pixel_bytes_per_row + | |
818 dst_point.X() * bytes_per_pixel; | |
819 else | |
820 dst_start_copy_position = | |
821 (dst_point.Y() + i) * dst_pixel_bytes_per_row + | |
822 dst_point.X() * bytes_per_pixel; | |
823 for (unsigned j = 0; | |
824 j < src_end_copy_position - src_start_copy_position; j++) { | |
825 // swizzle when necessary | |
826 if (kN32_SkColorType == kBGRA_8888_SkColorType) { | |
827 if (j % 4 == 0) | |
828 copied_data_buffer->Data()[dst_start_copy_position + j] = | |
829 src_addr[src_start_copy_position + j + 2]; | |
830 else if (j % 4 == 2) | |
831 copied_data_buffer->Data()[dst_start_copy_position + j] = | |
832 src_addr[src_start_copy_position + j - 2]; | |
833 else | |
834 copied_data_buffer->Data()[dst_start_copy_position + j] = | |
835 src_addr[src_start_copy_position + j]; | |
836 } else { | |
837 copied_data_buffer->Data()[dst_start_copy_position + j] = | |
838 src_addr[src_start_copy_position + j]; | |
839 } | |
840 } | |
841 } | |
842 } | |
843 sk_image = NewSkImageFromRaster(info, std::move(copied_data_buffer), | |
844 dst_pixel_bytes_per_row); | |
845 } | |
846 if (!sk_image) | |
847 return; | |
848 ApplyColorSpaceConversion(sk_image, parsed_options); | |
849 if (parsed_options.should_scale_input) { | 829 if (parsed_options.should_scale_input) { |
850 image_ = StaticBitmapImage::Create(ScaleSkImage( | 830 image_ = StaticBitmapImage::Create(ScaleSkImage( |
851 sk_image, parsed_options.resize_width, parsed_options.resize_height, | 831 sk_image, info, parsed_options.resize_width, |
852 parsed_options.resize_quality, | 832 parsed_options.resize_height, parsed_options.resize_quality)); |
853 parsed_options.color_params.GetSkColorType(), | |
854 data->GetSkColorSpace())); | |
855 } else { | 833 } else { |
856 image_ = StaticBitmapImage::Create(sk_image); | 834 image_ = StaticBitmapImage::Create(sk_image); |
857 } | 835 } |
858 if (!image_) | 836 if (!image_) |
859 return; | 837 return; |
860 image_->SetPremultiplied(parsed_options.premultiply_alpha); | 838 image_->SetPremultiplied(parsed_options.premultiply_alpha); |
| 839 SwizzleImageData(cropped_data, needs_swizzle); |
861 return; | 840 return; |
862 } | 841 } |
863 | 842 |
864 CanvasColorParams canvas_color_params; | 843 IntSize buffer_size = |
865 if (RuntimeEnabledFeatures::colorCanvasExtensionsEnabled()) { | 844 src_rect.IsEmpty() ? parsed_options.crop_rect.Size() : src_rect.Size(); |
866 ImageDataColorSettings color_settings; | |
867 data->getColorSettings(color_settings); | |
868 CanvasColorSpace canvas_color_space = | |
869 ImageData::GetCanvasColorSpace(color_settings.colorSpace()); | |
870 CanvasPixelFormat canvas_pixel_format = kRGBA8CanvasPixelFormat; | |
871 if (ImageData::GetImageDataStorageFormat(color_settings.storageFormat()) != | |
872 kUint8ClampedArrayStorageFormat) { | |
873 canvas_pixel_format = kF16CanvasPixelFormat; | |
874 } | |
875 canvas_color_params = | |
876 CanvasColorParams(canvas_color_space, canvas_pixel_format); | |
877 } | |
878 std::unique_ptr<ImageBuffer> buffer = | 845 std::unique_ptr<ImageBuffer> buffer = |
879 ImageBuffer::Create(parsed_options.crop_rect.Size(), kNonOpaque, | 846 ImageBuffer::Create(buffer_size, kNonOpaque, kDoNotInitializeImagePixels, |
880 kDoNotInitializeImagePixels, canvas_color_params); | 847 parsed_options.color_params); |
881 if (!buffer) | 848 if (!buffer) |
882 return; | 849 return; |
883 | |
884 if (src_rect.IsEmpty()) { | 850 if (src_rect.IsEmpty()) { |
885 image_ = StaticBitmapImage::Create(buffer->NewSkImageSnapshot( | 851 image_ = StaticBitmapImage::Create(buffer->NewSkImageSnapshot( |
886 kPreferNoAcceleration, kSnapshotReasonUnknown)); | 852 kPreferNoAcceleration, kSnapshotReasonUnknown)); |
887 return; | 853 return; |
888 } | 854 } |
889 | 855 |
890 IntPoint dst_point = IntPoint(std::min(0, -parsed_options.crop_rect.X()), | 856 buffer->PutByteArray(kUnmultiplied, color_corrected_pixels, |
891 std::min(0, -parsed_options.crop_rect.Y())); | 857 cropped_data->Size(), |
892 if (parsed_options.crop_rect.X() < 0) | 858 IntRect(IntPoint(), cropped_data->Size()), IntPoint()); |
893 dst_point.SetX(-parsed_options.crop_rect.X()); | |
894 if (parsed_options.crop_rect.Y() < 0) | |
895 dst_point.SetY(-parsed_options.crop_rect.Y()); | |
896 | 859 |
897 buffer->PutByteArray(kUnmultiplied, data->data()->Data(), data->Size(), | 860 SwizzleImageData(cropped_data, needs_swizzle); |
898 src_rect, dst_point); | |
899 sk_sp<SkImage> sk_image = | 861 sk_sp<SkImage> sk_image = |
900 buffer->NewSkImageSnapshot(kPreferNoAcceleration, kSnapshotReasonUnknown); | 862 buffer->NewSkImageSnapshot(kPreferNoAcceleration, kSnapshotReasonUnknown); |
901 if (parsed_options.flip_y) | |
902 sk_image = FlipSkImageVertically(sk_image.get(), kEnforceAlphaPremultiply); | |
903 if (!sk_image) | 863 if (!sk_image) |
904 return; | 864 return; |
| 865 |
905 if (parsed_options.should_scale_input) { | 866 if (parsed_options.should_scale_input) { |
906 sk_sp<SkSurface> surface = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul( | 867 sk_sp<SkSurface> surface = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul( |
907 parsed_options.resize_width, parsed_options.resize_height, | 868 parsed_options.resize_width, parsed_options.resize_height, |
908 data->GetSkColorSpace())); | 869 data->GetCanvasColorParams().GetSkColorSpaceForSkSurfaces())); |
909 if (!surface) | 870 if (!surface) |
910 return; | 871 return; |
911 SkPaint paint; | 872 SkPaint paint; |
912 paint.setFilterQuality(parsed_options.resize_quality); | 873 paint.setFilterQuality(parsed_options.resize_quality); |
913 SkRect dst_draw_rect = SkRect::MakeWH(parsed_options.resize_width, | 874 SkRect dst_draw_rect = SkRect::MakeWH(parsed_options.resize_width, |
914 parsed_options.resize_height); | 875 parsed_options.resize_height); |
915 surface->getCanvas()->drawImageRect(sk_image, dst_draw_rect, &paint); | 876 surface->getCanvas()->drawImageRect(sk_image, dst_draw_rect, &paint); |
916 sk_image = surface->makeImageSnapshot(); | 877 sk_image = surface->makeImageSnapshot(); |
917 } | 878 } |
918 ApplyColorSpaceConversion(sk_image, parsed_options); | |
919 image_ = StaticBitmapImage::Create(std::move(sk_image)); | 879 image_ = StaticBitmapImage::Create(std::move(sk_image)); |
920 } | 880 } |
921 | 881 |
922 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, | 882 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, |
923 Optional<IntRect> crop_rect, | 883 Optional<IntRect> crop_rect, |
924 const ImageBitmapOptions& options) { | 884 const ImageBitmapOptions& options) { |
| 885 LOG(ERROR) << "Entering..."; |
925 RefPtr<Image> input = bitmap->BitmapImage(); | 886 RefPtr<Image> input = bitmap->BitmapImage(); |
926 if (!input) | 887 if (!input) |
927 return; | 888 return; |
928 ParsedOptions parsed_options = | 889 ParsedOptions parsed_options = |
929 ParseOptions(options, crop_rect, input->Size()); | 890 ParseOptions(options, crop_rect, input->Size()); |
930 if (DstBufferSizeHasOverflow(parsed_options)) | 891 if (DstBufferSizeHasOverflow(parsed_options)) |
931 return; | 892 return; |
932 | 893 |
933 image_ = CropImageAndApplyColorSpaceConversion( | 894 image_ = CropImageAndApplyColorSpaceConversion( |
934 input.Get(), parsed_options, | 895 input.Get(), parsed_options, |
935 bitmap->IsPremultiplied() ? kPremultiplyAlpha : kDontPremultiplyAlpha, | 896 bitmap->IsPremultiplied() ? kPremultiplyAlpha : kDontPremultiplyAlpha, |
936 ColorBehavior::TransformToGlobalTarget()); | 897 ColorBehavior::TransformToGlobalTarget()); |
937 if (!image_) | 898 if (!image_) |
938 return; | 899 return; |
939 image_->SetOriginClean(bitmap->OriginClean()); | 900 image_->SetOriginClean(bitmap->OriginClean()); |
940 image_->SetPremultiplied(parsed_options.premultiply_alpha); | 901 image_->SetPremultiplied(parsed_options.premultiply_alpha); |
941 } | 902 } |
942 | 903 |
943 ImageBitmap::ImageBitmap(RefPtr<StaticBitmapImage> image, | 904 ImageBitmap::ImageBitmap(RefPtr<StaticBitmapImage> image, |
944 Optional<IntRect> crop_rect, | 905 Optional<IntRect> crop_rect, |
945 const ImageBitmapOptions& options) { | 906 const ImageBitmapOptions& options) { |
| 907 LOG(ERROR) << "Entering... "; |
946 bool origin_clean = image->OriginClean(); | 908 bool origin_clean = image->OriginClean(); |
947 ParsedOptions parsed_options = | 909 ParsedOptions parsed_options = |
948 ParseOptions(options, crop_rect, image->Size()); | 910 ParseOptions(options, crop_rect, image->Size()); |
949 if (DstBufferSizeHasOverflow(parsed_options)) | 911 if (DstBufferSizeHasOverflow(parsed_options)) |
950 return; | 912 return; |
951 | 913 |
| 914 LOG(ERROR) << "parsed_options.premultiply_alpha: " |
| 915 << parsed_options.premultiply_alpha; |
| 916 PrintSkImage(image.Get()->ImageForCurrentFrame()); |
| 917 |
952 image_ = CropImageAndApplyColorSpaceConversion( | 918 image_ = CropImageAndApplyColorSpaceConversion( |
953 image.Get(), parsed_options, kPremultiplyAlpha, | 919 image.Get(), parsed_options, kPremultiplyAlpha, |
954 ColorBehavior::TransformToGlobalTarget()); | 920 ColorBehavior::TransformToGlobalTarget()); |
| 921 LOG(ERROR) << "HERE"; |
955 if (!image_) | 922 if (!image_) |
956 return; | 923 return; |
| 924 LOG(ERROR) << "HERE"; |
| 925 |
| 926 PrintSkImage(image_.Get()->ImageForCurrentFrame()); |
957 | 927 |
958 image_->SetOriginClean(origin_clean); | 928 image_->SetOriginClean(origin_clean); |
959 image_->SetPremultiplied(parsed_options.premultiply_alpha); | 929 image_->SetPremultiplied(parsed_options.premultiply_alpha); |
960 } | 930 } |
961 | 931 |
962 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image) { | 932 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image) { |
| 933 LOG(ERROR) << "Entering..."; |
963 image_ = std::move(image); | 934 image_ = std::move(image); |
964 } | 935 } |
965 | 936 |
966 PassRefPtr<StaticBitmapImage> ImageBitmap::Transfer() { | 937 PassRefPtr<StaticBitmapImage> ImageBitmap::Transfer() { |
967 DCHECK(!IsNeutered()); | 938 DCHECK(!IsNeutered()); |
968 is_neutered_ = true; | 939 is_neutered_ = true; |
969 image_->Transfer(); | 940 image_->Transfer(); |
970 return std::move(image_); | 941 return std::move(image_); |
971 } | 942 } |
972 | 943 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1037 is_neutered_ = true; | 1008 is_neutered_ = true; |
1038 } | 1009 } |
1039 | 1010 |
1040 // static | 1011 // static |
1041 ImageBitmap* ImageBitmap::Take(ScriptPromiseResolver*, sk_sp<SkImage> image) { | 1012 ImageBitmap* ImageBitmap::Take(ScriptPromiseResolver*, sk_sp<SkImage> image) { |
1042 return ImageBitmap::Create(StaticBitmapImage::Create(std::move(image))); | 1013 return ImageBitmap::Create(StaticBitmapImage::Create(std::move(image))); |
1043 } | 1014 } |
1044 | 1015 |
1045 PassRefPtr<Uint8Array> ImageBitmap::CopyBitmapData(AlphaDisposition alpha_op, | 1016 PassRefPtr<Uint8Array> ImageBitmap::CopyBitmapData(AlphaDisposition alpha_op, |
1046 DataColorFormat format) { | 1017 DataColorFormat format) { |
| 1018 LOG(ERROR) << "Entering..."; |
1047 SkImageInfo info = SkImageInfo::Make( | 1019 SkImageInfo info = SkImageInfo::Make( |
1048 width(), height(), | 1020 width(), height(), |
1049 (format == kRGBAColorType) ? kRGBA_8888_SkColorType : kN32_SkColorType, | 1021 (format == kRGBAColorType) ? kRGBA_8888_SkColorType : kN32_SkColorType, |
1050 (alpha_op == kPremultiplyAlpha) ? kPremul_SkAlphaType | 1022 (alpha_op == kPremultiplyAlpha) ? kPremul_SkAlphaType |
1051 : kUnpremul_SkAlphaType); | 1023 : kUnpremul_SkAlphaType); |
1052 RefPtr<Uint8Array> dst_pixels = | 1024 RefPtr<Uint8Array> dst_pixels = |
1053 CopySkImageData(image_->ImageForCurrentFrame().get(), info); | 1025 CopySkImageData(image_->ImageForCurrentFrame().get(), info); |
1054 return dst_pixels.Release(); | 1026 return dst_pixels.Release(); |
1055 } | 1027 } |
1056 | 1028 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1093 return ScriptPromise(); | 1065 return ScriptPromise(); |
1094 return ImageBitmapSource::FulfillImageBitmap( | 1066 return ImageBitmapSource::FulfillImageBitmap( |
1095 script_state, Create(this, crop_rect, options)); | 1067 script_state, Create(this, crop_rect, options)); |
1096 } | 1068 } |
1097 | 1069 |
1098 PassRefPtr<Image> ImageBitmap::GetSourceImageForCanvas( | 1070 PassRefPtr<Image> ImageBitmap::GetSourceImageForCanvas( |
1099 SourceImageStatus* status, | 1071 SourceImageStatus* status, |
1100 AccelerationHint, | 1072 AccelerationHint, |
1101 SnapshotReason, | 1073 SnapshotReason, |
1102 const FloatSize&) { | 1074 const FloatSize&) { |
| 1075 LOG(ERROR) << "HERE too ..."; |
1103 *status = kNormalSourceImageStatus; | 1076 *status = kNormalSourceImageStatus; |
1104 if (!image_) | 1077 if (!image_) |
1105 return nullptr; | 1078 return nullptr; |
1106 if (image_->IsPremultiplied()) | 1079 if (image_->IsPremultiplied()) |
1107 return image_; | 1080 return image_; |
1108 // Skia does not support drawing unpremul SkImage on SkCanvas. | 1081 // Skia does not support drawing unpremul SkImage on SkCanvas. |
1109 // Premultiply and return. | 1082 // Premultiply and return. |
1110 sk_sp<SkImage> premul_sk_image = | 1083 sk_sp<SkImage> premul_sk_image = |
1111 UnPremulSkImageToPremul(image_->ImageForCurrentFrame().get()); | 1084 UnPremulSkImageToPremul(image_->ImageForCurrentFrame().get()); |
1112 return StaticBitmapImage::Create(premul_sk_image); | 1085 return StaticBitmapImage::Create(premul_sk_image); |
1113 } | 1086 } |
1114 | 1087 |
1115 void ImageBitmap::AdjustDrawRects(FloatRect* src_rect, | 1088 void ImageBitmap::AdjustDrawRects(FloatRect* src_rect, |
1116 FloatRect* dst_rect) const {} | 1089 FloatRect* dst_rect) const {} |
1117 | 1090 |
1118 FloatSize ImageBitmap::ElementSize(const FloatSize&) const { | 1091 FloatSize ImageBitmap::ElementSize(const FloatSize&) const { |
1119 return FloatSize(width(), height()); | 1092 return FloatSize(width(), height()); |
1120 } | 1093 } |
1121 | 1094 |
1122 DEFINE_TRACE(ImageBitmap) {} | 1095 DEFINE_TRACE(ImageBitmap) {} |
1123 | 1096 |
1124 } // namespace blink | 1097 } // namespace blink |
OLD | NEW |