2
* Copyright 2014 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.
17
// Author: Victor Chudnovsky
19
#ifndef PAGESPEED_KERNEL_IMAGE_IMAGE_UTIL_H_
20
#define PAGESPEED_KERNEL_IMAGE_IMAGE_UTIL_H_
24
#include "pagespeed/kernel/base/basictypes.h"
25
#include "pagespeed/kernel/base/countdown_timer.h"
26
#include "pagespeed/kernel/base/string.h"
27
#include "pagespeed/kernel/base/string_util.h"
29
namespace net_instaweb {
36
namespace image_compression {
47
UNSUPPORTED, // Not supported.
48
RGB_888, // RGB triplets, 24 bits per pixel.
49
RGBA_8888, // RGB triplet plus alpha channel, 32 bits per pixel.
50
GRAY_8 // Grayscale, 8 bits per pixel.
62
const uint8_t kAlphaOpaque = 255;
63
const uint8_t kAlphaTransparent = 0;
64
typedef uint8_t PixelRgbaChannels[RGBA_NUM_CHANNELS];
66
// Packs the given A, R, G, B values into a single uint32.
67
inline uint32_t PackAsArgb(uint8_t alpha,
72
(static_cast<uint32_t>(alpha) << 24) |
78
// Packs a pixel's color channel data in RGBA format to a single
79
// uint32_t in ARGB format.
80
inline uint32_t RgbaToPackedArgb(const PixelRgbaChannels rgba) {
81
return PackAsArgb(rgba[RGBA_ALPHA],
87
// Packs a pixel's color channel data in RGB format to a single
88
// uint32_t in ARGB format.
89
inline uint32_t RgbToPackedArgb(const PixelRgbaChannels rgba) {
90
return PackAsArgb(kAlphaOpaque,
96
// Converts a pixel's grayscale data into a single uint32_t in ARGB
98
inline uint32_t GrayscaleToPackedArgb(const uint8_t luminance) {
99
return PackAsArgb(kAlphaOpaque,
105
// Sizes that can be measured in units of pixels: width, height,
106
// number of frames (a third dimension of the image), and indices into
108
typedef uint32 size_px;
110
// Returns the MIME-type string corresponding to the given ImageFormat.
111
const char* ImageFormatToMimeTypeString(ImageFormat image_type);
113
// Returns a string representation of the given ImageFormat.
114
const char* ImageFormatToString(ImageFormat image_type);
116
// Returns a string representation of the given PixelFormat.
117
const char* GetPixelFormatString(PixelFormat pixel_format);
119
// Returns the number of bytes needed to encode each pixel in the
121
size_t GetBytesPerPixel(PixelFormat pixel_format);
123
// Returns format of the image by inspecting magic numbers (cetain values at
124
// cetain bytes) in the file content. This method is super fast, but if a
125
// random binary file happens to have the magic numbers, it will incorrectly
126
// reports a format for the file. The problem will be corrected when the binary
128
ImageFormat ComputeImageFormat(const StringPiece& buf,
129
bool* is_webp_lossless_alpha);
131
// Class for managing image conversion timeouts.
132
class ConversionTimeoutHandler {
134
ConversionTimeoutHandler(int64 time_allowed_ms,
135
net_instaweb::Timer* timer,
136
net_instaweb::MessageHandler* handler) :
137
countdown_timer_(timer, NULL, time_allowed_ms),
138
time_allowed_ms_(time_allowed_ms),
140
was_timed_out_(false),
144
// Returns true if (1) the timer has not expired, or (2) the timer has
145
// expired but "output_" is not empty which means that some data are
146
// being written to it. This method can be passed as progress hook to
147
// WebP writer. Input parameter "user_data" must point to a
148
// ConversionTimeoutHandler object.
149
static bool Continue(int percent, void* user_data);
151
void Start(GoogleString* output) {
153
countdown_timer_.Reset(time_allowed_ms_);
157
time_elapsed_ms_ = countdown_timer_.TimeElapsedMs();
160
bool was_timed_out() const { return was_timed_out_; }
161
int64 time_elapsed_ms() const { return time_elapsed_ms_; }
164
net_instaweb::CountdownTimer countdown_timer_;
165
const int64 time_allowed_ms_;
166
int64 time_elapsed_ms_;
168
GoogleString* output_;
169
net_instaweb::MessageHandler* handler_;
172
} // namespace image_compression
174
} // namespace pagespeed
176
#endif // PAGESPEED_KERNEL_IMAGE_IMAGE_UTIL_H_