2
* Copyright 2010 Google Inc.
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
16
// Author: jmaessen@google.com (Jan Maessen)
18
#ifndef NET_INSTAWEB_REWRITER_PUBLIC_IMAGE_URL_ENCODER_H_
19
#define NET_INSTAWEB_REWRITER_PUBLIC_IMAGE_URL_ENCODER_H_
21
#include "net/instaweb/rewriter/cached_result.pb.h"
22
#include "net/instaweb/util/public/basictypes.h"
23
#include "net/instaweb/util/public/gtest_prod.h"
24
#include "net/instaweb/util/public/string.h"
25
#include "net/instaweb/util/public/string_util.h"
26
#include "net/instaweb/util/public/url_segment_encoder.h"
28
namespace net_instaweb {
31
class RequestProperties;
36
// This class implements the encoding of image urls with optional additional
37
// dimension metadata. It basically prepends characters indicating image
38
// dimensions on the page, webp eligibility, and mobile user agent eligibility
39
// (this information is conveyed in the ResourceContext).
40
// http://...path.../50x75xurl... No webp, image is 50x75 on page
41
// http://...path.../50x75wurl... Webp requested, image is 50x75 on page
42
// http://...path.../50x75mxurl...
43
// No webp, for mobile user agent, image is 50x75 on page
44
// http://...path.../50x75mwurl...
45
// Webp requested, for mobile user agent, image is 50x75 on page
46
// http://...path.../50xNxurl.. No webp, image is 50 wide, no height given
47
// http://...path.../50xNwurl... Webp, image is 50 wide, no height given
48
// http://...path.../Nx75xurl... No webp, image is 75 high, no width given
49
// http://...path.../Nx75wurl... Webp, image is 75 high, no width given.
50
// http://...path.../50xNmxurl.. No webp, image is 50 wide, mobile
51
// http://...path.../50xNmwurl... Webp, image is 50 wide, mobile
52
// http://...path.../Nx75mxurl... No webp, image is 75 high, mobile
53
// http://...path.../Nx75mwurl... Webp, image is 75 high, mobile
54
// http://...path.../xurl... Page does not specify both dimensions. No webp.
55
// http://...path.../wurl... Webp requested, page missing dimensions.
56
// http://...path.../xurl... Page does not specify any dimension. No webp.
57
// http://...path.../wurl... Webp requested, page missing either dimension.
58
// http://...path.../mxurl...
59
// No webp, for mobile user agent, page does not specify dimensions.
60
// http://...path.../mwurl...
61
// Webp requested, for mobile user agent, page missing dimensions.
62
class ImageUrlEncoder : public UrlSegmentEncoder {
64
// Area threshold that determines whether we use
65
// Image*RecompressionQualityForSmallScreens to set WebP/Jpeg quality.
66
// The intent is for phones and small tablets (e.g., Nexus 7) to be in.
67
static const int kSmallScreenSizeThresholdArea;
70
virtual ~ImageUrlEncoder();
72
virtual void Encode(const StringVector& urls,
73
const ResourceContext* dim,
74
GoogleString* rewritten_url) const;
76
virtual bool Decode(const StringPiece& url_segment,
79
MessageHandler* handler) const;
81
// Set LibWebp level according to the user agent.
82
// TODO(poojatandon): Pass a user agent object with its webp-cabaple bits
83
// pre-analyzed (not just the string from the request headers), since
84
// checking webp level related code doesn't belong here.
85
static void SetLibWebpLevel(const RewriteOptions& options,
86
const RequestProperties& request_properties,
87
ResourceContext* resource_context);
89
// Sets webp and mobile capability in resource context.
91
// The parameters to this method are urls, rewrite options & resource context.
92
// Since rewrite options are not changed, we have passed const reference and
93
// resource context is modified and can be NULL, hence we pass as a pointer.
94
static void SetWebpAndMobileUserAgent(const RewriteDriver& driver,
95
ResourceContext* context);
97
// Determines whether the given URL is a pagespeed-rewritten webp URL.
98
static bool IsWebpRewrittenUrl(const GoogleUrl& gurl);
100
// Flag whether this device has a small screen, which determines what
101
// Jpeg/WebP quality to use.
102
static void SetSmallScreen(const RewriteDriver& driver,
103
ResourceContext* context);
105
// Set context for screen resolution.
106
static void SetUserAgentScreenResolution(
107
RewriteDriver* driver, ResourceContext* context);
109
// Helper function to generate Metadata cache key from ResourceContext.
110
static GoogleString CacheKeyFromResourceContext(
111
const ResourceContext& resource_context);
113
static bool HasDimensions(const ResourceContext& data) {
114
return (data.has_desired_image_dims() &&
115
HasValidDimensions(data.desired_image_dims()));
118
static bool HasValidDimensions(const ImageDim& dims) {
119
return (dims.has_width() && dims.has_height());
122
static bool HasDimension(const ResourceContext& data) {
123
return (data.has_desired_image_dims() &&
124
HasValidDimension(data.desired_image_dims()));
127
static bool HasValidDimension(const ImageDim& dims) {
128
return (dims.has_width() || dims.has_height());
132
FRIEND_TEST(ImageRewriteTest, SquashImagesForMobileScreen);
133
FRIEND_TEST(ImageUrlEncoderTest, UserAgentScreenResolution);
135
// Returns true if screen width and height are normalized according to a
136
// predefined list of screen resolutions (see implementation header document
137
// for more details).
138
static bool GetNormalizedScreenResolution(
139
int screen_width, int screen_height, int* normalized_width,
140
int* normalized_height);
142
DISALLOW_COPY_AND_ASSIGN(ImageUrlEncoder);
145
} // namespace net_instaweb
147
#endif // NET_INSTAWEB_REWRITER_PUBLIC_IMAGE_URL_ENCODER_H_