OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include "WEBPImageDecoder.h" | 30 #include "WEBPImageDecoder.h" |
31 | 31 |
32 #if USE(WEBP) | 32 #if USE(WEBP) |
33 | 33 |
34 #include "webp/decode.h" | 34 #include "webp/decode.h" |
35 | 35 |
36 #if PLATFORM(CHROMIUM) | 36 #if PLATFORM(CHROMIUM) |
37 #include "TraceEvent.h" | 37 #include "TraceEvent.h" |
38 #endif | 38 #endif |
39 | 39 |
| 40 // backward emulation for earlier versions than 0.1.99 |
| 41 #if (WEBP_DECODER_ABI_VERSION < 0x0163) |
| 42 #define MODE_rgbA MODE_RGBA |
| 43 #define MODE_bgrA MODE_BGRA |
| 44 #endif |
| 45 |
40 #if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN) | 46 #if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN) |
41 inline WEBP_CSP_MODE outputMode() { return MODE_RGBA; } | 47 inline WEBP_CSP_MODE outputMode(bool hasAlpha) { return hasAlpha ? MODE_rgbA : M
ODE_RGBA; } |
42 #elif USE(SKIA) && SK_B32_SHIFT | 48 #elif USE(SKIA) && SK_B32_SHIFT |
43 inline WEBP_CSP_MODE outputMode() { return MODE_RGBA; } | 49 inline WEBP_CSP_MODE outputMode(bool hasAlpha) { return hasAlpha ? MODE_rgbA : M
ODE_RGBA; } |
44 #else // LITTLE_ENDIAN, output BGRA pixels. | 50 #else // LITTLE_ENDIAN, output BGRA pixels. |
45 inline WEBP_CSP_MODE outputMode() { return MODE_BGRA; } | 51 inline WEBP_CSP_MODE outputMode(bool hasAlpha) { return hasAlpha ? MODE_bgrA : M
ODE_BGRA; } |
46 #endif | 52 #endif |
47 | 53 |
48 namespace WebCore { | 54 namespace WebCore { |
49 | 55 |
50 WEBPImageDecoder::WEBPImageDecoder(ImageSource::AlphaOption alphaOption, | 56 WEBPImageDecoder::WEBPImageDecoder(ImageSource::AlphaOption alphaOption, |
51 ImageSource::GammaAndColorProfileOption gamma
AndColorProfileOption) | 57 ImageSource::GammaAndColorProfileOption gamma
AndColorProfileOption) |
52 : ImageDecoder(alphaOption, gammaAndColorProfileOption) | 58 : ImageDecoder(alphaOption, gammaAndColorProfileOption) |
53 , m_decoder(0) | 59 , m_decoder(0) |
| 60 , m_hasAlpha(false) |
54 { | 61 { |
55 } | 62 } |
56 | 63 |
57 WEBPImageDecoder::~WEBPImageDecoder() | 64 WEBPImageDecoder::~WEBPImageDecoder() |
58 { | 65 { |
59 if (m_decoder) | 66 if (m_decoder) |
60 WebPIDelete(m_decoder); | 67 WebPIDelete(m_decoder); |
61 m_decoder = 0; | 68 m_decoder = 0; |
62 } | 69 } |
63 | 70 |
(...skipping 30 matching lines...) Expand all Loading... |
94 return false; | 101 return false; |
95 | 102 |
96 const uint8_t* dataBytes = reinterpret_cast<const uint8_t*>(m_data->data()); | 103 const uint8_t* dataBytes = reinterpret_cast<const uint8_t*>(m_data->data()); |
97 const size_t dataSize = m_data->size(); | 104 const size_t dataSize = m_data->size(); |
98 | 105 |
99 if (!ImageDecoder::isSizeAvailable()) { | 106 if (!ImageDecoder::isSizeAvailable()) { |
100 static const size_t imageHeaderSize = 30; | 107 static const size_t imageHeaderSize = 30; |
101 if (dataSize < imageHeaderSize) | 108 if (dataSize < imageHeaderSize) |
102 return false; | 109 return false; |
103 int width, height; | 110 int width, height; |
| 111 #if (WEBP_DECODER_ABI_VERSION >= 0x0163) |
| 112 WebPBitstreamFeatures features; |
| 113 if (WebPGetFeatures(dataBytes, dataSize, &features) != VP8_STATUS_OK) |
| 114 return setFailed(); |
| 115 width = features.width; |
| 116 height = features.height; |
| 117 m_hasAlpha = features.has_alpha; |
| 118 #else |
| 119 // Earlier version won't be able to display WebP files with alpha. |
104 if (!WebPGetInfo(dataBytes, dataSize, &width, &height)) | 120 if (!WebPGetInfo(dataBytes, dataSize, &width, &height)) |
105 return setFailed(); | 121 return setFailed(); |
| 122 m_hasAlpha = false; |
| 123 #endif |
106 if (!setSize(width, height)) | 124 if (!setSize(width, height)) |
107 return setFailed(); | 125 return setFailed(); |
108 } | 126 } |
109 | 127 |
110 ASSERT(ImageDecoder::isSizeAvailable()); | 128 ASSERT(ImageDecoder::isSizeAvailable()); |
111 if (onlySize) | 129 if (onlySize) |
112 return true; | 130 return true; |
113 | 131 |
114 ASSERT(!m_frameBufferCache.isEmpty()); | 132 ASSERT(!m_frameBufferCache.isEmpty()); |
115 ImageFrame& buffer = m_frameBufferCache[0]; | 133 ImageFrame& buffer = m_frameBufferCache[0]; |
116 ASSERT(buffer.status() != ImageFrame::FrameComplete); | 134 ASSERT(buffer.status() != ImageFrame::FrameComplete); |
117 | 135 |
118 if (buffer.status() == ImageFrame::FrameEmpty) { | 136 if (buffer.status() == ImageFrame::FrameEmpty) { |
119 if (!buffer.setSize(size().width(), size().height())) | 137 if (!buffer.setSize(size().width(), size().height())) |
120 return setFailed(); | 138 return setFailed(); |
121 buffer.setStatus(ImageFrame::FramePartial); | 139 buffer.setStatus(ImageFrame::FramePartial); |
122 buffer.setHasAlpha(false); // FIXME: webp does not support alpha yet. | 140 buffer.setHasAlpha(m_hasAlpha); |
123 buffer.setOriginalFrameRect(IntRect(IntPoint(), size())); | 141 buffer.setOriginalFrameRect(IntRect(IntPoint(), size())); |
124 } | 142 } |
125 | 143 |
126 if (!m_decoder) { | 144 if (!m_decoder) { |
127 int rowStride = size().width() * sizeof(ImageFrame::PixelData); | 145 int rowStride = size().width() * sizeof(ImageFrame::PixelData); |
128 uint8_t* output = reinterpret_cast<uint8_t*>(buffer.getAddr(0, 0)); | 146 uint8_t* output = reinterpret_cast<uint8_t*>(buffer.getAddr(0, 0)); |
129 int outputSize = size().height() * rowStride; | 147 int outputSize = size().height() * rowStride; |
130 m_decoder = WebPINewRGB(outputMode(), output, outputSize, rowStride); | 148 m_decoder = WebPINewRGB(outputMode(m_hasAlpha), output, outputSize, rowS
tride); |
131 if (!m_decoder) | 149 if (!m_decoder) |
132 return setFailed(); | 150 return setFailed(); |
133 } | 151 } |
134 | 152 |
135 switch (WebPIUpdate(m_decoder, dataBytes, dataSize)) { | 153 switch (WebPIUpdate(m_decoder, dataBytes, dataSize)) { |
136 case VP8_STATUS_OK: | 154 case VP8_STATUS_OK: |
137 buffer.setStatus(ImageFrame::FrameComplete); | 155 buffer.setStatus(ImageFrame::FrameComplete); |
138 WebPIDelete(m_decoder); | 156 WebPIDelete(m_decoder); |
139 m_decoder = 0; | 157 m_decoder = 0; |
140 return true; | 158 return true; |
141 case VP8_STATUS_SUSPENDED: | 159 case VP8_STATUS_SUSPENDED: |
142 return false; | 160 return false; |
143 default: | 161 default: |
144 WebPIDelete(m_decoder); | 162 WebPIDelete(m_decoder); |
145 m_decoder = 0; | 163 m_decoder = 0; |
146 return setFailed(); | 164 return setFailed(); |
147 } | 165 } |
148 } | 166 } |
149 | 167 |
150 } // namespace WebCore | 168 } // namespace WebCore |
151 | 169 |
152 #endif | 170 #endif |
OLD | NEW |