1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_IMAGE_FETCHER_IOS_WEBP_DECODER_H_
6 #define COMPONENTS_IMAGE_FETCHER_IOS_WEBP_DECODER_H_
7 
8 #import <Foundation/Foundation.h>
9 #include <stddef.h>
10 
11 #include <memory>
12 
13 #include "base/memory/ref_counted.h"
14 #include "third_party/libwebp/src/webp/decode.h"
15 
16 @class NSData;
17 
18 namespace webp_transcode {
19 
20 // Decodes a WebP image into either JPEG, PNG or uncompressed TIFF.
21 class WebpDecoder : public base::RefCountedThreadSafe<WebpDecoder> {
22  public:
23   // Format of the decoded image.
24   // This enum is used for UMA reporting, keep it in sync with the histogram
25   // definition.
26   enum DecodedImageFormat { JPEG = 1, PNG, TIFF, DECODED_FORMAT_COUNT };
27 
28   class Delegate : public base::RefCountedThreadSafe<WebpDecoder::Delegate> {
29    public:
30     virtual void OnFinishedDecoding(bool success) = 0;
31     virtual void SetImageFeatures(size_t total_size,  // In bytes.
32                                   DecodedImageFormat format) = 0;
33     virtual void OnDataDecoded(NSData* data) = 0;
34 
35    protected:
36     friend class base::RefCountedThreadSafe<WebpDecoder::Delegate>;
~Delegate()37     virtual ~Delegate() {}
38   };
39 
40   explicit WebpDecoder(WebpDecoder::Delegate* delegate);
41 
42   // Returns an NSData object containing the decoded image data of the given
43   // webp_image. Returns nil in case of failure.
44   static NSData* DecodeWebpImage(NSData* webp_image);
45 
46   // Returns true if the given image_data is a WebP image.
47   //
48   // Every WebP file contains a 12 byte file header in the beginning of the
49   // file.
50   // A WebP file header starts with the four ASCII characters "RIFF". The next
51   // four bytes contain the image size and the last four header bytes contain
52   // the four ASCII characters "WEBP".
53   //
54   // WebP file header:
55   //                                  1 1
56   // Byte Nr.     0 1 2 3 4 5 6 7 8 9 0 1
57   // Byte value [ R I F F ? ? ? ? W E B P  ]
58   //
59   // For more information see:
60   // https://developers.google.com/speed/webp/docs/riff_container#webp_file_header
61   static bool IsWebpImage(const std::string& image_data);
62 
63   // For tests.
64   static size_t GetHeaderSize();
65 
66   // Main entry point.
67   void OnDataReceived(NSData* data);
68 
69   // Stops the decoding.
70   void Stop();
71 
72  private:
73   struct WebPIDecoderDeleter {
operatorWebPIDecoderDeleter74     inline void operator()(WebPIDecoder* ptr) const { WebPIDelete(ptr); }
75   };
76 
77   enum State { READING_FEATURES, READING_DATA, DONE };
78 
79   friend class base::RefCountedThreadSafe<WebpDecoder>;
80   virtual ~WebpDecoder();
81 
82   // Implements WebP image decoding state machine steps.
83   void DoReadFeatures(NSData* data);
84   void DoReadData(NSData* data);
85   bool DoSendData();
86 
87   scoped_refptr<WebpDecoder::Delegate> delegate_;
88   WebPDecoderConfig config_;
89   WebpDecoder::State state_;
90   std::unique_ptr<WebPIDecoder, WebPIDecoderDeleter> incremental_decoder_;
91   __strong NSData* output_buffer_;
92   __strong NSMutableData* features_;
93   int has_alpha_;
94 };
95 
96 }  // namespace webp_transcode
97 
98 #endif  // COMPONENTS_IMAGE_FETCHER_IOS_WEBP_DECODER_H_
99