| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/loader/resource/ImageResourceContent.h" | 5 #include "core/loader/resource/ImageResourceContent.h" |
| 6 | 6 |
| 7 #include "core/loader/resource/ImageResource.h" | 7 #include "core/loader/resource/ImageResource.h" |
| 8 #include "core/loader/resource/ImageResourceInfo.h" | 8 #include "core/loader/resource/ImageResourceInfo.h" |
| 9 #include "core/loader/resource/ImageResourceObserver.h" | 9 #include "core/loader/resource/ImageResourceObserver.h" |
| 10 #include "core/svg/graphics/SVGImage.h" | 10 #include "core/svg/graphics/SVGImage.h" |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 int64_t length = m_image->data() ? m_image->data()->size() : 0; | 291 int64_t length = m_image->data() ? m_image->data()->size() : 0; |
| 292 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-length); | 292 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-length); |
| 293 | 293 |
| 294 // If our Image has an observer, it's always us so we need to clear the back | 294 // If our Image has an observer, it's always us so we need to clear the back |
| 295 // pointer before dropping our reference. | 295 // pointer before dropping our reference. |
| 296 m_image->clearImageObserver(); | 296 m_image->clearImageObserver(); |
| 297 m_image.clear(); | 297 m_image.clear(); |
| 298 m_sizeAvailable = Image::SizeUnavailable; | 298 m_sizeAvailable = Image::SizeUnavailable; |
| 299 } | 299 } |
| 300 | 300 |
| 301 // Determines if |response| likely contains the entire resource for the purposes |
| 302 // of determining whether or not to show a placeholder, e.g. if the server |
| 303 // responded with a full 200 response or if the full image is smaller than the |
| 304 // requested range. |
| 305 static bool isEntireResource(const ResourceResponse& response) { |
| 306 if (response.httpStatusCode() != 206) |
| 307 return true; |
| 308 |
| 309 int64_t firstBytePosition = -1, lastBytePosition = -1, instanceLength = -1; |
| 310 return parseContentRangeHeaderFor206( |
| 311 response.httpHeaderField("Content-Range"), &firstBytePosition, |
| 312 &lastBytePosition, &instanceLength) && |
| 313 firstBytePosition == 0 && lastBytePosition + 1 == instanceLength; |
| 314 } |
| 315 |
| 316 static bool shouldShowFullImageInsteadOfPlaceholder( |
| 317 const ResourceResponse& response, |
| 318 const Image* image) { |
| 319 if (!isEntireResource(response)) |
| 320 return false; |
| 321 if (image && !image->isNull()) |
| 322 return true; |
| 323 |
| 324 // Don't treat a complete and broken image as a placeholder if the response |
| 325 // code is something other than a 4xx or 5xx error. This is done to prevent |
| 326 // reissuing the request in cases like "204 No Content" responses to tracking |
| 327 // requests triggered by <img> tags, and <img> tags used to preload non-image |
| 328 // resources. |
| 329 return response.httpStatusCode() < 400 || response.httpStatusCode() >= 600; |
| 330 } |
| 331 |
| 301 void ImageResourceContent::updateImage(PassRefPtr<SharedBuffer> data, | 332 void ImageResourceContent::updateImage(PassRefPtr<SharedBuffer> data, |
| 302 UpdateImageOption updateImageOption, | 333 UpdateImageOption updateImageOption, |
| 303 bool allDataReceived) { | 334 bool allDataReceived) { |
| 304 TRACE_EVENT0("blink", "ImageResourceContent::updateImage"); | 335 TRACE_EVENT0("blink", "ImageResourceContent::updateImage"); |
| 305 | 336 |
| 306 // Clears the existing image, if instructed by |updateImageOption|. | 337 // Clears the existing image, if instructed by |updateImageOption|. |
| 307 switch (updateImageOption) { | 338 switch (updateImageOption) { |
| 308 case ClearAndUpdateImage: | 339 case ClearAndUpdateImage: |
| 309 case ClearImageAndNotifyObservers: | 340 case ClearImageAndNotifyObservers: |
| 310 clearImage(); | 341 clearImage(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 330 DCHECK(m_image); | 361 DCHECK(m_image); |
| 331 m_sizeAvailable = m_image->setData(std::move(data), allDataReceived); | 362 m_sizeAvailable = m_image->setData(std::move(data), allDataReceived); |
| 332 } | 363 } |
| 333 | 364 |
| 334 // Go ahead and tell our observers to try to draw if we have either | 365 // Go ahead and tell our observers to try to draw if we have either |
| 335 // received all the data or the size is known. Each chunk from the network | 366 // received all the data or the size is known. Each chunk from the network |
| 336 // causes observers to repaint, which will force that chunk to decode. | 367 // causes observers to repaint, which will force that chunk to decode. |
| 337 if (m_sizeAvailable == Image::SizeUnavailable && !allDataReceived) | 368 if (m_sizeAvailable == Image::SizeUnavailable && !allDataReceived) |
| 338 return; | 369 return; |
| 339 | 370 |
| 340 if (m_info->isPlaceholder() && allDataReceived && m_image && | 371 if (m_info->isPlaceholder() && allDataReceived) { |
| 341 !m_image->isNull()) { | 372 if (shouldShowFullImageInsteadOfPlaceholder(response(), |
| 342 if (m_sizeAvailable == Image::SizeAvailable) { | 373 m_image.get())) { |
| 343 // TODO(sclittle): Show the original image if the response consists of | 374 m_info->setIsPlaceholder(false); |
| 344 // the entire image, such as if the entire image response body is | 375 } else if (m_image && !m_image->isNull()) { |
| 345 // smaller than the requested range. | |
| 346 IntSize dimensions = m_image->size(); | 376 IntSize dimensions = m_image->size(); |
| 347 | |
| 348 clearImage(); | 377 clearImage(); |
| 349 m_image = PlaceholderImage::create(this, dimensions); | 378 m_image = PlaceholderImage::create(this, dimensions); |
| 350 } else { | |
| 351 // Clear the image so that it gets treated like a decoding error, | |
| 352 // since the attempt to build a placeholder image failed. | |
| 353 clearImage(); | |
| 354 } | 379 } |
| 355 } | 380 } |
| 381 |
| 356 if (!m_image || m_image->isNull()) { | 382 if (!m_image || m_image->isNull()) { |
| 357 clearImage(); | 383 clearImage(); |
| 358 m_info->decodeError(allDataReceived); | 384 m_info->decodeError(allDataReceived); |
| 359 } | 385 } |
| 360 break; | 386 break; |
| 361 } | 387 } |
| 362 | 388 |
| 363 // Notifies the observers. | 389 // Notifies the observers. |
| 364 // It would be nice to only redraw the decoded band of the image, but with the | 390 // It would be nice to only redraw the decoded band of the image, but with the |
| 365 // current design (decoding delayed until painting) that seems hard. | 391 // current design (decoding delayed until painting) that seems hard. |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 | 505 |
| 480 const ResourceResponse& ImageResourceContent::response() const { | 506 const ResourceResponse& ImageResourceContent::response() const { |
| 481 return m_info->response(); | 507 return m_info->response(); |
| 482 } | 508 } |
| 483 | 509 |
| 484 const ResourceError& ImageResourceContent::resourceError() const { | 510 const ResourceError& ImageResourceContent::resourceError() const { |
| 485 return m_info->resourceError(); | 511 return m_info->resourceError(); |
| 486 } | 512 } |
| 487 | 513 |
| 488 } // namespace blink | 514 } // namespace blink |
| OLD | NEW |