blob: 20f3ee818ce4e0665912e2f707e2367df01f2670 [file] [log] [blame]
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Author: Huibao Lin
#ifndef PAGESPEED_KERNEL_IMAGE_IMAGE_RESIZER_H_
#define PAGESPEED_KERNEL_IMAGE_IMAGE_RESIZER_H_
#include <cstddef>
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/message_handler.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/image/image_util.h"
#include "pagespeed/kernel/image/scanline_interface.h"
#include "pagespeed/kernel/image/scanline_status.h"
namespace pagespeed {
namespace image_compression {
using net_instaweb::MessageHandler;
class ResizeRow;
class ResizeCol;
// Class ScanlineResizer resizes an image, and outputs a scanline at a time.
// To use it, you need to provide an initialized reader implementing
// ScanlineReaderInterface. The ScanlineResizer object will instruct the reader
// to fetch the image scanlines required for the resized scanline.
//
// You can specify the width, the height, or both in pixels. If you want to
// preserve the aspect ratio, you can specify only one of them, and pass in
// kPreserveAspectRatio for the other one.
//
// Currently, ScanlineResizer only supports shrinking. It works best when the
// image shrinks significantly, e.g, by more than 2x times.
class ScanlineResizer : public ScanlineReaderInterface {
public:
explicit ScanlineResizer(MessageHandler* handler);
virtual ~ScanlineResizer();
// Initializes the resizer with a reader and the desired output size.
bool Initialize(ScanlineReaderInterface* reader,
size_t output_width,
size_t output_height);
// Reads the next available scanline. Returns an error if the next scanline
// is not available. This can happen when the reader cannot provide enough
// image rows, or when all of the scanlines have been read.
virtual ScanlineStatus ReadNextScanlineWithStatus(void** out_scanline_bytes);
// Resets the resizer to its initial state. Always returns true.
virtual bool Reset();
// Returns number of bytes required to store a scanline.
virtual size_t GetBytesPerScanline() {
return static_cast<size_t>(elements_per_row_);
}
// Returns true if there are more scanlines to read. Returns false if the
// object has not been initialized or all of the scanlines have been read.
virtual bool HasMoreScanLines();
// Returns the height of the image.
virtual size_t GetImageHeight() {
return static_cast<size_t>(height_);
}
// Returns the width of the image.
virtual size_t GetImageWidth() {
return static_cast<size_t>(width_);
}
// Returns the pixel format of the image.
virtual PixelFormat GetPixelFormat() {
return reader_->GetPixelFormat();
}
// Returns true if the image is encoded in progressive / interlacing format.
virtual bool IsProgressive() {
return reader_->IsProgressive();
}
// This method should not be called. If it does get called, in DEBUG mode it
// will throw a FATAL error and in RELEASE mode it does nothing.
virtual ScanlineStatus InitializeWithStatus(const void* image_buffer,
size_t buffer_length);
static const size_t kPreserveAspectRatio = 0;
private:
ScanlineReaderInterface* reader_;
// Horizontal resizer.
net_instaweb::scoped_ptr<ResizeRow> resizer_x_;
// Vertical resizer.
net_instaweb::scoped_ptr<ResizeCol> resizer_y_;
net_instaweb::scoped_array<uint8> output_;
int width_;
int height_;
int elements_per_row_;
// Buffer for storing the intermediate results.
net_instaweb::scoped_array<float> buffer_;
int bytes_per_buffer_row_;
MessageHandler* message_handler_;
DISALLOW_COPY_AND_ASSIGN(ScanlineResizer);
};
} // namespace image_compression
} // namespace pagespeed
#endif // PAGESPEED_KERNEL_IMAGE_IMAGE_RESIZER_H_