Remove unused private field from WEBPImageDecoder
[WebKit-https.git] / Source / WebCore / platform / image-decoders / webp / WEBPImageDecoder.cpp
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "WEBPImageDecoder.h"
31
32 #if USE(WEBP)
33
34 // Backward emulation for earlier versions than 0.1.99.
35 #if (WEBP_DECODER_ABI_VERSION < 0x0163)
36 #define MODE_rgbA MODE_RGBA
37 #define MODE_bgrA MODE_BGRA
38 #endif
39
40 #if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN)
41 inline WEBP_CSP_MODE outputMode(bool hasAlpha) { return hasAlpha ? MODE_rgbA : MODE_RGBA; }
42 #else // LITTLE_ENDIAN, output BGRA pixels.
43 inline WEBP_CSP_MODE outputMode(bool hasAlpha) { return hasAlpha ? MODE_bgrA : MODE_BGRA; }
44 #endif
45
46 namespace WebCore {
47
48 WEBPImageDecoder::WEBPImageDecoder(ImageSource::AlphaOption alphaOption,
49                                    ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
50     : ImageDecoder(alphaOption, gammaAndColorProfileOption)
51     , m_decoder(0)
52     , m_hasAlpha(false)
53 {
54 }
55
56 WEBPImageDecoder::~WEBPImageDecoder()
57 {
58     clear();
59 }
60
61 void WEBPImageDecoder::clear()
62 {
63     if (m_decoder)
64         WebPIDelete(m_decoder);
65     m_decoder = 0;
66 }
67
68 bool WEBPImageDecoder::isSizeAvailable()
69 {
70     if (!ImageDecoder::isSizeAvailable())
71          decode(true);
72
73     return ImageDecoder::isSizeAvailable();
74 }
75
76 ImageFrame* WEBPImageDecoder::frameBufferAtIndex(size_t index)
77 {
78     if (index)
79         return 0;
80
81     if (m_frameBufferCache.isEmpty()) {
82         m_frameBufferCache.resize(1);
83         m_frameBufferCache[0].setPremultiplyAlpha(m_premultiplyAlpha);
84     }
85
86     ImageFrame& frame = m_frameBufferCache[0];
87     if (frame.status() != ImageFrame::FrameComplete)
88         decode(false);
89     return &frame;
90 }
91
92 bool WEBPImageDecoder::decode(bool onlySize)
93 {
94     if (failed())
95         return false;
96
97     const uint8_t* dataBytes = reinterpret_cast<const uint8_t*>(m_data->data());
98     const size_t dataSize = m_data->size();
99
100     if (!ImageDecoder::isSizeAvailable()) {
101         static const size_t imageHeaderSize = 30;
102         if (dataSize < imageHeaderSize)
103             return false;
104         int width, height;
105 #if (WEBP_DECODER_ABI_VERSION >= 0x0163)
106         WebPBitstreamFeatures features;
107         if (WebPGetFeatures(dataBytes, dataSize, &features) != VP8_STATUS_OK)
108             return setFailed();
109         width = features.width;
110         height = features.height;
111         m_hasAlpha = features.has_alpha;
112 #else
113         // Earlier version won't be able to display WebP files with alpha.
114         if (!WebPGetInfo(dataBytes, dataSize, &width, &height))
115             return setFailed();
116         m_hasAlpha = false;
117 #endif
118         if (!setSize(width, height))
119             return setFailed();
120     }
121
122     ASSERT(ImageDecoder::isSizeAvailable());
123     if (onlySize)
124         return true;
125
126     ASSERT(!m_frameBufferCache.isEmpty());
127     ImageFrame& buffer = m_frameBufferCache[0];
128     ASSERT(buffer.status() != ImageFrame::FrameComplete);
129
130     if (buffer.status() == ImageFrame::FrameEmpty) {
131         if (!buffer.setSize(size().width(), size().height()))
132             return setFailed();
133         buffer.setStatus(ImageFrame::FramePartial);
134         buffer.setHasAlpha(m_hasAlpha);
135         buffer.setOriginalFrameRect(IntRect(IntPoint(), size()));
136     }
137
138     if (!m_decoder) {
139         WEBP_CSP_MODE mode = outputMode(m_hasAlpha);
140         if (!m_premultiplyAlpha)
141             mode = outputMode(false);
142         int rowStride = size().width() * sizeof(ImageFrame::PixelData);
143         uint8_t* output = reinterpret_cast<uint8_t*>(buffer.getAddr(0, 0));
144         int outputSize = size().height() * rowStride;
145         m_decoder = WebPINewRGB(mode, output, outputSize, rowStride);
146         if (!m_decoder)
147             return setFailed();
148     }
149
150     switch (WebPIUpdate(m_decoder, dataBytes, dataSize)) {
151     case VP8_STATUS_OK:
152         buffer.setStatus(ImageFrame::FrameComplete);
153         clear();
154         return true;
155     case VP8_STATUS_SUSPENDED:
156         return false;
157     default:
158         clear();                         
159         return setFailed();
160     }
161 }
162
163 } // namespace WebCore
164
165 #endif