~alinuxninja/nginx-edge/trunk

« back to all changes in this revision

Viewing changes to debian/modules/ngx_pagespeed/psol/include/net/instaweb/rewriter/public/image.h

  • Committer: Vivian
  • Date: 2015-12-04 18:20:11 UTC
  • Revision ID: git-v1:a36f2bc32e884f7473b3a47040e5411306144d7d
* Do not extract psol.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2010 Google Inc.
3
 
 *
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
7
 
 *
8
 
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 
 *
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.
15
 
 */
16
 
 
17
 
// Author: jmaessen@google.com (Jan Maessen)
18
 
 
19
 
#ifndef NET_INSTAWEB_REWRITER_PUBLIC_IMAGE_H_
20
 
#define NET_INSTAWEB_REWRITER_PUBLIC_IMAGE_H_
21
 
 
22
 
#include <cstddef>
23
 
 
24
 
#include "net/instaweb/rewriter/image_types.pb.h"
25
 
#include "net/instaweb/rewriter/cached_result.pb.h"
26
 
#include "net/instaweb/rewriter/public/rewrite_options.h"
27
 
#include "net/instaweb/util/public/basictypes.h"
28
 
#include "net/instaweb/util/public/string.h"
29
 
#include "net/instaweb/util/public/string_util.h"
30
 
 
31
 
namespace net_instaweb {
32
 
class Histogram;
33
 
class MessageHandler;
34
 
class Timer;
35
 
class Variable;
36
 
struct ContentType;
37
 
 
38
 
class Image {
39
 
 public:
40
 
  // Images that are in the process of being transformed are represented by an
41
 
  // Image.  This class encapsulates various operations that are sensitive to
42
 
  // the format of the compressed image file and of the image libraries we are
43
 
  // using.  In particular, the timing of compression and decompression
44
 
  // operations may be a bit unexpected, because we may do these operations
45
 
  // early in order to retrieve image metadata, or we may choose to skip them
46
 
  // entirely if we don't need them or don't understand how to do them.
47
 
  //
48
 
  // In future we may need to plumb this to other data sources or change how
49
 
  // metadata is retrieved; the object is to do so locally in this class without
50
 
  // disrupting any of its clients.
51
 
 
52
 
  enum PreferredWebp {
53
 
    WEBP_NONE = 0,
54
 
    WEBP_LOSSY,
55
 
    WEBP_LOSSLESS
56
 
  };
57
 
 
58
 
  struct ConversionBySourceVariable {
59
 
    ConversionBySourceVariable()
60
 
        : timeout_count(NULL),
61
 
          success_ms(NULL),
62
 
          failure_ms(NULL) {}
63
 
 
64
 
    Variable* timeout_count;  // # of timed-out conversions.
65
 
    Histogram* success_ms;    // Successful conversion duration.
66
 
    Histogram* failure_ms;    // Failed (and non-timed-out) conversion duration.
67
 
  };
68
 
 
69
 
  struct ConversionVariables {
70
 
    enum VariableType {
71
 
      FROM_UNKNOWN_FORMAT = 0,
72
 
      FROM_GIF,
73
 
      FROM_PNG,
74
 
      FROM_JPEG,
75
 
      OPAQUE,
76
 
      NONOPAQUE,
77
 
      NUM_VARIABLE_TYPE
78
 
    };
79
 
    ConversionBySourceVariable* Get(VariableType var_type) {
80
 
      if ((var_type < FROM_UNKNOWN_FORMAT) ||
81
 
          (var_type >= NUM_VARIABLE_TYPE)) {
82
 
        return NULL;
83
 
      }
84
 
      return &(vars[var_type]);
85
 
    }
86
 
 
87
 
    ConversionBySourceVariable vars[NUM_VARIABLE_TYPE];
88
 
  };
89
 
 
90
 
  struct CompressionOptions {
91
 
    CompressionOptions()
92
 
        : preferred_webp(WEBP_NONE),
93
 
          allow_webp_alpha(false),
94
 
          webp_quality(RewriteOptions::kDefaultImageRecompressQuality),
95
 
          jpeg_quality(RewriteOptions::kDefaultImageRecompressQuality),
96
 
          progressive_jpeg_min_bytes(
97
 
              RewriteOptions::kDefaultProgressiveJpegMinBytes),
98
 
          progressive_jpeg(false),
99
 
          convert_gif_to_png(false),
100
 
          convert_png_to_jpeg(false),
101
 
          convert_jpeg_to_webp(false),
102
 
          recompress_jpeg(false),
103
 
          recompress_png(false),
104
 
          recompress_webp(false),
105
 
          retain_color_profile(false),
106
 
          retain_color_sampling(false),
107
 
          retain_exif_data(false),
108
 
          use_transparent_for_blank_image(false),
109
 
          jpeg_num_progressive_scans(
110
 
              RewriteOptions::kDefaultImageJpegNumProgressiveScans),
111
 
          webp_conversion_timeout_ms(-1),
112
 
          conversions_attempted(0),
113
 
          preserve_lossless(false),
114
 
          webp_conversion_variables(NULL) {}
115
 
 
116
 
    // These options are set by the client to specify what type of
117
 
    // conversion to perform:
118
 
    PreferredWebp preferred_webp;
119
 
    bool allow_webp_alpha;
120
 
    int64 webp_quality;
121
 
    int64 jpeg_quality;
122
 
    int64 progressive_jpeg_min_bytes;
123
 
    bool progressive_jpeg;
124
 
    bool convert_gif_to_png;
125
 
    bool convert_png_to_jpeg;
126
 
    bool convert_jpeg_to_webp;
127
 
    bool recompress_jpeg;
128
 
    bool recompress_png;
129
 
    bool recompress_webp;
130
 
    bool retain_color_profile;
131
 
    bool retain_color_sampling;
132
 
    bool retain_exif_data;
133
 
    bool use_transparent_for_blank_image;
134
 
    int64 jpeg_num_progressive_scans;
135
 
    int64 webp_conversion_timeout_ms;
136
 
 
137
 
    // These fields are set by the conversion routines to report
138
 
    // characteristics of the conversion process.
139
 
    int conversions_attempted;
140
 
    bool preserve_lossless;
141
 
 
142
 
    ConversionVariables* webp_conversion_variables;
143
 
  };
144
 
 
145
 
  virtual ~Image();
146
 
 
147
 
  // static method to convert image type to content type.
148
 
  static const ContentType* TypeToContentType(ImageType t);
149
 
 
150
 
  // Stores the image dimensions in natural_dim (on success, sets
151
 
  // natural_dim->{width, height} and
152
 
  // ImageUrlEncoder::HasValidDimensions(natural_dim) == true).  This
153
 
  // method can fail (ImageUrlEncoder::HasValidDimensions(natural_dim)
154
 
  // == false) for various reasons: we don't understand the image
155
 
  // format, we can't find the headers, the library doesn't support a
156
 
  // particular encoding, etc.  In that case the other fields are left
157
 
  // alone.
158
 
  virtual void Dimensions(ImageDim* natural_dim) = 0;
159
 
 
160
 
  // Returns the size of original input in bytes.
161
 
  size_t input_size() const {
162
 
    return original_contents_.size();
163
 
  }
164
 
 
165
 
  // Returns the size of output image in bytes.
166
 
  size_t output_size() {
167
 
    size_t ret;
168
 
    if (output_valid_ || ComputeOutputContents()) {
169
 
      ret = output_contents_.size();
170
 
    } else {
171
 
      ret = input_size();
172
 
    }
173
 
    return ret;
174
 
  }
175
 
 
176
 
  ImageType image_type() {
177
 
    if (image_type_ == IMAGE_UNKNOWN) {
178
 
      ComputeImageType();
179
 
    }
180
 
    return image_type_;
181
 
  }
182
 
 
183
 
  // If we had arbitrary license to convert to any webp format, what's the
184
 
  // minimal webp library support that would be required for this image?
185
 
  ResourceContext::LibWebpLevel MinimalWebpSupport() {
186
 
    if (!rewrite_attempted_) {
187
 
      ComputeOutputContents();
188
 
    }
189
 
    return minimal_webp_support_;
190
 
  }
191
 
 
192
 
  // Changes the size of the image to the given width and height.  This will run
193
 
  // image processing on the image, and return false if the image processing
194
 
  // fails.  Otherwise the image contents and type can change.
195
 
  virtual bool ResizeTo(const ImageDim& new_dim) = 0;
196
 
 
197
 
  // Enable the transformation to low res image. If low res image is enabled,
198
 
  // all jpeg images are transformed to low quality jpeg images and all webp
199
 
  // images to low quality webp images, if possible.
200
 
  virtual void SetTransformToLowRes() = 0;
201
 
 
202
 
  // Returns image-appropriate content type, or NULL if no content type is
203
 
  // known.  Result is a top-level const pointer and should not be deleted etc.
204
 
  const ContentType* content_type() {
205
 
    return TypeToContentType(image_type());
206
 
  }
207
 
 
208
 
  // Returns the best known image contents.  If image type is not understood,
209
 
  // then Contents() will have NULL data().
210
 
  StringPiece Contents();
211
 
 
212
 
  // Draws the given image on top of this one at the given offset.  Returns true
213
 
  // if successful.
214
 
  virtual bool DrawImage(Image* image, int x, int y) = 0;
215
 
 
216
 
  // Attempts to decode this image and load its raster into memory.  If this
217
 
  // returns false, future calls to DrawImage and ResizeTo will fail.
218
 
  //
219
 
  // If output_useful is true, the decoded version might be written out
220
 
  // directly to user, so it may be worthwhile to make it efficient.
221
 
  virtual bool EnsureLoaded(bool output_useful) = 0;
222
 
 
223
 
  // Returns the image URL.
224
 
  virtual const GoogleString& url() = 0;
225
 
 
226
 
  // Returns the debug message.
227
 
  virtual const GoogleString& debug_message() = 0;
228
 
 
229
 
  // Returns the resized image debug message.
230
 
  virtual const GoogleString& resize_debug_message() = 0;
231
 
 
232
 
 protected:
233
 
  explicit Image(const StringPiece& original_contents);
234
 
  explicit Image(ImageType type);
235
 
 
236
 
  // Internal helpers
237
 
  virtual void ComputeImageType() = 0;
238
 
  virtual bool ComputeOutputContents() = 0;
239
 
 
240
 
  // Inject desired resized dimensions directly for testing.
241
 
  virtual void SetResizedDimensions(const ImageDim& dim) = 0;
242
 
 
243
 
  // Determines whether it's a good idea to convert this image to progressive
244
 
  // jpeg.
245
 
  virtual bool ShouldConvertToProgressive(int64 quality) const = 0;
246
 
 
247
 
 
248
 
  ImageType image_type_;  // Lazily initialized, initially IMAGE_UNKNOWN.
249
 
  const StringPiece original_contents_;
250
 
  GoogleString output_contents_;  // Lazily filled.
251
 
  bool output_valid_;             // Indicates output_contents_ now correct.
252
 
  bool rewrite_attempted_;        // Indicates if we tried rewriting for this.
253
 
  ResourceContext::LibWebpLevel minimal_webp_support_;
254
 
 
255
 
 private:
256
 
  friend class ImageTestingPeer;
257
 
  friend class ImageTest;
258
 
 
259
 
  DISALLOW_COPY_AND_ASSIGN(Image);
260
 
};
261
 
 
262
 
// Image owns none of its inputs.  All of the arguments to NewImage(...) (the
263
 
// original_contents in particular) must outlive the Image object itself.  The
264
 
// intent is that an Image is created in a scoped fashion from an existing known
265
 
// resource.
266
 
//
267
 
// The options should be set via Image::SetOptions after construction, before
268
 
// the image is used for anything but determining its natural dimension size.
269
 
//
270
 
// TODO(jmarantz): It would seem natural to fold the ImageOptions into the
271
 
// Image object itself.
272
 
Image* NewImage(const StringPiece& original_contents,
273
 
                const GoogleString& url,
274
 
                const StringPiece& file_prefix,
275
 
                Image::CompressionOptions* options,
276
 
                Timer* timer,
277
 
                MessageHandler* handler);
278
 
 
279
 
// Creates a blank image of the given dimensions and type.
280
 
// For now, this is assumed to be an 8-bit 4-channel image transparent image.
281
 
Image* BlankImageWithOptions(int width, int height, ImageType type,
282
 
                             const StringPiece& tmp_dir,
283
 
                             Timer* timer,
284
 
                             MessageHandler* handler,
285
 
                             Image::CompressionOptions* options);
286
 
 
287
 
}  // namespace net_instaweb
288
 
 
289
 
#endif  // NET_INSTAWEB_REWRITER_PUBLIC_IMAGE_H_