Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Unified Diff: third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp

Issue 1647703006: Track positions of dimensions in image files (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Updated GIF dimensions UMA logic Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
diff --git a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
index b940a89422b145bc6945c61eb426658016c51d68..c092b30aa72fd7ecd2debfdcc6c37c7790cab0dc 100644
--- a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
@@ -38,6 +38,9 @@
#include "platform/image-decoders/jpeg/JPEGImageDecoder.h"
#include "platform/PlatformInstrumentation.h"
+#include "public/platform/Platform.h"
+
+#include <stdint.h>
extern "C" {
#include <stdio.h> // jpeglib.h needs stdio FILE.
@@ -76,6 +79,38 @@ const int exifMarker = JPEG_APP0 + 1;
// JPEG only supports a denominator of 8.
const unsigned scaleDenominator = 8;
+
+// Returns a 16-bit integer with big-endian representation from a byte array.
+unsigned getUint16(const char* p)
+{
+ return ((*((unsigned char*)p)) << 8) + *((unsigned char*)(p + 1));
+}
+
+// Returns the number of bytes that must be fetched before the image dimensions can be determined.
+// Used for metrics only. Returns 0 if dimensions not found.
+size_t getDimensionsOffset(const RefPtr<blink::SharedBuffer>& m_data)
+{
+ const char* segment;
+ size_t pos = 0;
+ int height = 0, width = 0;
+ size_t length = m_data->getSomeData(segment, pos);
+ if (length < 2 || 0xFFD8 != getUint16(&segment[0]))
+ return 0;
+ pos += 2;
+ while ((length = m_data->getSomeData(segment, pos))) {
+ if (length < 2)
+ return 0;
+ int marker = getUint16(&segment[0]) & 0xfffc;
+ if (marker == 0xffc0)
+ break;
+ pos += 2 + getUint16(&segment[2]);
+ }
+ if (length < 8)
+ return 0;
+ // Height and width are two bytes each and are at bytes 5 and 7 of this segment, respectively.
+ return pos + 8;
+}
+
} // namespace
namespace blink {
@@ -470,6 +505,7 @@ public:
if (m_info.scale_num != m_info.scale_denom)
overrideColorSpace = JCS_UNKNOWN;
jpeg_calc_output_dimensions(&m_info);
+ m_decoder->setSizeOffset(m_nextReadPosition);
m_decoder->setDecodedSize(m_info.output_width, m_info.output_height);
m_decoder->setOrientation(readImageOrientation(info()));
@@ -771,7 +807,7 @@ void term_source(j_decompress_ptr jd)
JPEGImageDecoder::JPEGImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption colorOptions, size_t maxDecodedBytes)
: ImageDecoder(alphaOption, colorOptions, maxDecodedBytes)
- , m_hasColorProfile(false)
+ , m_sizeOffset(0), m_sizeOffsetOptimized(0), m_hasColorProfile(false)
{
}
@@ -1070,6 +1106,13 @@ void JPEGImageDecoder::decode(bool onlySize)
// has failed.
if (!m_reader->decode(onlySize) && isAllDataReceived())
setFailed();
+ // Decoding should happen only once.
+ if (!onlySize && isComplete(this, onlySize)) {
+ Platform::current()->histogramCustomCounts(
+ "Blink.Images.SizeOffsetOptimized_JPEG", getDimensionsOffset(m_data), 1, 1000000, 50);
+ Platform::current()->histogramCustomCounts(
+ "Blink.Images.SizeOffset_JPEG", m_sizeOffset, 1, 1000000, 50);
+ }
// If decoding is done or failed, we don't need the JPEGImageReader anymore.
if (isComplete(this, onlySize) || failed())

Powered by Google App Engine
This is Rietveld 408576698