| 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 |