| /* |
| * Copyright 2009 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: Bryan McQuade, Matthew Steele, Satyanarayana Manyam |
| |
| #ifndef PAGESPEED_KERNEL_IMAGE_JPEG_OPTIMIZER_H_ |
| #define PAGESPEED_KERNEL_IMAGE_JPEG_OPTIMIZER_H_ |
| |
| #include <setjmp.h> |
| #include <cstddef> |
| #include "pagespeed/kernel/base/basictypes.h" |
| #include "pagespeed/kernel/base/string.h" |
| #include "pagespeed/kernel/image/image_util.h" |
| #include "pagespeed/kernel/image/scanline_interface.h" |
| #include "pagespeed/kernel/image/scanline_status.h" |
| |
| // DO NOT INCLUDE LIBJPEG HEADERS HERE. Doing so causes build errors |
| // on Windows. |
| |
| namespace net_instaweb { |
| class MessageHandler; |
| } |
| |
| namespace pagespeed { |
| |
| namespace image_compression { |
| |
| using net_instaweb::MessageHandler; |
| |
| enum ColorSampling { |
| RETAIN, |
| YUV420, |
| YUV422, |
| YUV444 |
| }; |
| |
| struct JpegLossyOptions { |
| JpegLossyOptions() : quality(85), num_scans(-1), color_sampling(YUV420) {} |
| // jpeg_quality - Can take values in the range [1,100]. |
| // For web images, the preferred value for quality is 85. |
| // For smaller images like thumbnails, the preferred value for quality is 75. |
| // Setting it to values below 50 is generally not preferable. |
| int quality; |
| |
| // No. of progressive scan that needs to be included in the final output. |
| // -1 indicates to use all scans that are present. |
| int num_scans; |
| |
| // Color sampling that needs to be used while recompressing the image. |
| ColorSampling color_sampling; |
| }; |
| |
| struct JpegCompressionOptions { |
| JpegCompressionOptions() |
| : progressive(false), retain_color_profile(false), |
| retain_exif_data(false), lossy(false) {} |
| |
| // Whether or not to produce a progressive JPEG. This parameter will only be |
| // applied for images with YCbCr colorspace, and it is ignored for other |
| // colorspaces. |
| bool progressive; |
| |
| // If set to 'true' any color profile information is retained. |
| bool retain_color_profile; |
| |
| // If set to 'true' any exif information is retained. |
| bool retain_exif_data; |
| |
| // Whether or not to use lossy compression. |
| bool lossy; |
| |
| // Lossy compression options. Only applicable if lossy (above) is set to true. |
| JpegLossyOptions lossy_options; |
| }; |
| |
| // Performs lossless optimization, that is, the output image will be |
| // pixel-for-pixel identical to the input image. |
| bool OptimizeJpeg(const GoogleString &original, |
| GoogleString *compressed, |
| MessageHandler* handler); |
| |
| // Performs JPEG optimizations with the provided options. |
| bool OptimizeJpegWithOptions(const GoogleString &original, |
| GoogleString *compressed, |
| const JpegCompressionOptions &options, |
| MessageHandler* handler); |
| |
| // User of this class must call this functions in the following sequence |
| // func () { |
| // JpegScanlineWriter jpeg_writer; |
| // jmp_buf env; |
| // if (setjmp(env)) { |
| // jpeg_writer.AbortWrite(); |
| // return; |
| // } |
| // jpeg_writer.SetJmpBufEnv(&env); |
| // if (jpeg_writer.Init(width, height, format)) { |
| // jpeg_writer.SetJpegCompressParams(quality); |
| // jpeg_writer.InitializeWrite(out); |
| // while(has_lines_to_write) { |
| // writer.WriteNextScanline(next_scan_line); |
| // } |
| // writer.FinalizeWrite() |
| // } |
| // } |
| class JpegScanlineWriter : public ScanlineWriterInterface { |
| public: |
| explicit JpegScanlineWriter(MessageHandler* handler); |
| virtual ~JpegScanlineWriter(); |
| |
| // Set the environment for longjmp calls. |
| void SetJmpBufEnv(jmp_buf* env); |
| |
| // This function is only called when jpeg library call longjmp for |
| // cleaning up the jpeg structs. |
| void AbortWrite(); |
| |
| virtual ScanlineStatus InitWithStatus(const size_t width, const size_t height, |
| PixelFormat pixel_format); |
| // Set the compression options via 'params', which should be a |
| // JpegCompressionOptions*. Since writer only supports lossy |
| // encoding, it is an error to pass in a 'params' that has the lossy |
| // field set to false. |
| virtual ScanlineStatus InitializeWriteWithStatus(const void* params, |
| GoogleString *compressed); |
| virtual ScanlineStatus WriteNextScanlineWithStatus( |
| const void *scanline_bytes); |
| virtual ScanlineStatus FinalizeWriteWithStatus(); |
| |
| private: |
| // Since writer only supports lossy encoding, it is an error to pass |
| // in a compression options that has lossy field set to false. |
| void SetJpegCompressParams(const JpegCompressionOptions& options); |
| |
| // Opaque struct that is defined in the cc file and contains our |
| // JPEG-compressor-specific structures. |
| struct Data; |
| Data* const data_; |
| MessageHandler* message_handler_; |
| |
| DISALLOW_COPY_AND_ASSIGN(JpegScanlineWriter); |
| }; |
| |
| } // namespace image_compression |
| |
| } // namespace pagespeed |
| |
| #endif // PAGESPEED_KERNEL_IMAGE_JPEG_OPTIMIZER_H_ |