Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Side by Side Diff: src/codec/SkSampledCodec.cpp

Issue 1518743002: Add reallyHasAlpha() to SkAndroidCodec (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Change comment on onReallyHasAlpha Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/codec/SkSampledCodec.h ('k') | src/codec/SkWebpAdapterCodec.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkCodec.h" 8 #include "SkCodec.h"
9 #include "SkCodecPriv.h" 9 #include "SkCodecPriv.h"
10 #include "SkMath.h" 10 #include "SkMath.h"
11 #include "SkSampledCodec.h" 11 #include "SkSampledCodec.h"
12 12
13 SkSampledCodec::SkSampledCodec(SkCodec* codec) 13 SkSampledCodec::SkSampledCodec(SkCodec* codec)
14 : INHERITED(codec->getInfo()) 14 : INHERITED(codec)
15 , fCodec(codec)
16 {} 15 {}
17 16
18 SkISize SkSampledCodec::accountForNativeScaling(int* sampleSizePtr, int* nativeS ampleSize) const { 17 SkISize SkSampledCodec::accountForNativeScaling(int* sampleSizePtr, int* nativeS ampleSize) const {
19 SkISize preSampledSize = fCodec->getInfo().dimensions(); 18 SkISize preSampledSize = this->codec()->getInfo().dimensions();
20 int sampleSize = *sampleSizePtr; 19 int sampleSize = *sampleSizePtr;
21 SkASSERT(sampleSize > 1); 20 SkASSERT(sampleSize > 1);
22 21
23 if (nativeSampleSize) { 22 if (nativeSampleSize) {
24 *nativeSampleSize = 1; 23 *nativeSampleSize = 1;
25 } 24 }
26 25
27 // Only JPEG supports native downsampling. 26 // Only JPEG supports native downsampling.
28 if (fCodec->getEncodedFormat() == kJPEG_SkEncodedFormat) { 27 if (this->codec()->getEncodedFormat() == kJPEG_SkEncodedFormat) {
29 // See if libjpeg supports this scale directly 28 // See if libjpeg supports this scale directly
30 switch (sampleSize) { 29 switch (sampleSize) {
31 case 2: 30 case 2:
32 case 4: 31 case 4:
33 case 8: 32 case 8:
34 // This class does not need to do any sampling. 33 // This class does not need to do any sampling.
35 *sampleSizePtr = 1; 34 *sampleSizePtr = 1;
36 return fCodec->getScaledDimensions(get_scale_from_sample_size(sa mpleSize)); 35 return this->codec()->getScaledDimensions(get_scale_from_sample_ size(sampleSize));
37 default: 36 default:
38 break; 37 break;
39 } 38 }
40 39
41 // Check if sampleSize is a multiple of something libjpeg can support. 40 // Check if sampleSize is a multiple of something libjpeg can support.
42 int remainder; 41 int remainder;
43 const int sampleSizes[] = { 8, 4, 2 }; 42 const int sampleSizes[] = { 8, 4, 2 };
44 for (int supportedSampleSize : sampleSizes) { 43 for (int supportedSampleSize : sampleSizes) {
45 int actualSampleSize; 44 int actualSampleSize;
46 SkTDivMod(sampleSize, supportedSampleSize, &actualSampleSize, &remai nder); 45 SkTDivMod(sampleSize, supportedSampleSize, &actualSampleSize, &remai nder);
47 if (0 == remainder) { 46 if (0 == remainder) {
48 float scale = get_scale_from_sample_size(supportedSampleSize); 47 float scale = get_scale_from_sample_size(supportedSampleSize);
49 48
50 // fCodec will scale to this size. 49 // this->codec() will scale to this size.
51 preSampledSize = fCodec->getScaledDimensions(scale); 50 preSampledSize = this->codec()->getScaledDimensions(scale);
52 51
53 // And then this class will sample it. 52 // And then this class will sample it.
54 *sampleSizePtr = actualSampleSize; 53 *sampleSizePtr = actualSampleSize;
55 if (nativeSampleSize) { 54 if (nativeSampleSize) {
56 *nativeSampleSize = supportedSampleSize; 55 *nativeSampleSize = supportedSampleSize;
57 } 56 }
58 break; 57 break;
59 } 58 }
60 } 59 }
61 } 60 }
62 61
63 return preSampledSize; 62 return preSampledSize;
64 } 63 }
65 64
66 SkISize SkSampledCodec::onGetSampledDimensions(int sampleSize) const { 65 SkISize SkSampledCodec::onGetSampledDimensions(int sampleSize) const {
67 const SkISize size = this->accountForNativeScaling(&sampleSize); 66 const SkISize size = this->accountForNativeScaling(&sampleSize);
68 return SkISize::Make(get_scaled_dimension(size.width(), sampleSize), 67 return SkISize::Make(get_scaled_dimension(size.width(), sampleSize),
69 get_scaled_dimension(size.height(), sampleSize)); 68 get_scaled_dimension(size.height(), sampleSize));
70 } 69 }
71 70
72 SkCodec::Result SkSampledCodec::onGetAndroidPixels(const SkImageInfo& info, void * pixels, 71 SkCodec::Result SkSampledCodec::onGetAndroidPixels(const SkImageInfo& info, void * pixels,
73 size_t rowBytes, const AndroidOptions& options) { 72 size_t rowBytes, const AndroidOptions& options) {
74 // Create an Options struct for the codec. 73 // Create an Options struct for the codec.
75 SkCodec::Options codecOptions; 74 SkCodec::Options codecOptions;
76 codecOptions.fZeroInitialized = options.fZeroInitialized; 75 codecOptions.fZeroInitialized = options.fZeroInitialized;
77 76
78 SkIRect* subset = options.fSubset; 77 SkIRect* subset = options.fSubset;
79 if (!subset || subset->size() == fCodec->getInfo().dimensions()) { 78 if (!subset || subset->size() == this->codec()->getInfo().dimensions()) {
80 if (fCodec->dimensionsSupported(info.dimensions())) { 79 if (this->codec()->dimensionsSupported(info.dimensions())) {
81 return fCodec->getPixels(info, pixels, rowBytes, &codecOptions, opti ons.fColorPtr, 80 return this->codec()->getPixels(info, pixels, rowBytes, &codecOption s,
82 options.fColorCount); 81 options.fColorPtr, options.fColorCount);
83 } 82 }
84 83
85 // If the native codec does not support the requested scale, scale by sa mpling. 84 // If the native codec does not support the requested scale, scale by sa mpling.
86 return this->sampledDecode(info, pixels, rowBytes, options); 85 return this->sampledDecode(info, pixels, rowBytes, options);
87 } 86 }
88 87
89 // We are performing a subset decode. 88 // We are performing a subset decode.
90 int sampleSize = options.fSampleSize; 89 int sampleSize = options.fSampleSize;
91 SkISize scaledSize = this->getSampledDimensions(sampleSize); 90 SkISize scaledSize = this->getSampledDimensions(sampleSize);
92 if (!fCodec->dimensionsSupported(scaledSize)) { 91 if (!this->codec()->dimensionsSupported(scaledSize)) {
93 // If the native codec does not support the requested scale, scale by sa mpling. 92 // If the native codec does not support the requested scale, scale by sa mpling.
94 return this->sampledDecode(info, pixels, rowBytes, options); 93 return this->sampledDecode(info, pixels, rowBytes, options);
95 } 94 }
96 95
97 // Calculate the scaled subset bounds. 96 // Calculate the scaled subset bounds.
98 int scaledSubsetX = subset->x() / sampleSize; 97 int scaledSubsetX = subset->x() / sampleSize;
99 int scaledSubsetY = subset->y() / sampleSize; 98 int scaledSubsetY = subset->y() / sampleSize;
100 int scaledSubsetWidth = info.width(); 99 int scaledSubsetWidth = info.width();
101 int scaledSubsetHeight = info.height(); 100 int scaledSubsetHeight = info.height();
102 101
103 // Start the scanline decode. 102 // Start the scanline decode.
104 SkIRect scanlineSubset = SkIRect::MakeXYWH(scaledSubsetX, 0, scaledSubsetWid th, 103 SkIRect scanlineSubset = SkIRect::MakeXYWH(scaledSubsetX, 0, scaledSubsetWid th,
105 scaledSize.height()); 104 scaledSize.height());
106 codecOptions.fSubset = &scanlineSubset; 105 codecOptions.fSubset = &scanlineSubset;
107 SkCodec::Result result = fCodec->startScanlineDecode(info.makeWH(scaledSize. width(), 106 SkCodec::Result result = this->codec()->startScanlineDecode(info.makeWH(scal edSize.width(),
108 scaledSize.height()), &codecOptions, options.fColorPtr, options.fCol orCount); 107 scaledSize.height()), &codecOptions, options.fColorPtr, options.fCol orCount);
109 if (SkCodec::kSuccess != result) { 108 if (SkCodec::kSuccess != result) {
110 return result; 109 return result;
111 } 110 }
112 111
113 // At this point, we are only concerned with subsetting. Either no scale wa s 112 // At this point, we are only concerned with subsetting. Either no scale wa s
114 // requested, or the fCodec is handling the scale. 113 // requested, or the this->codec() is handling the scale.
115 switch (fCodec->getScanlineOrder()) { 114 switch (this->codec()->getScanlineOrder()) {
116 case SkCodec::kTopDown_SkScanlineOrder: 115 case SkCodec::kTopDown_SkScanlineOrder:
117 case SkCodec::kNone_SkScanlineOrder: { 116 case SkCodec::kNone_SkScanlineOrder: {
118 if (!fCodec->skipScanlines(scaledSubsetY)) { 117 if (!this->codec()->skipScanlines(scaledSubsetY)) {
119 fCodec->fillIncompleteImage(info, pixels, rowBytes, options.fZer oInitialized, 118 this->codec()->fillIncompleteImage(info, pixels, rowBytes, optio ns.fZeroInitialized,
120 scaledSubsetHeight, 0); 119 scaledSubsetHeight, 0);
121 return SkCodec::kIncompleteInput; 120 return SkCodec::kIncompleteInput;
122 } 121 }
123 122
124 int decodedLines = fCodec->getScanlines(pixels, scaledSubsetHeight, rowBytes); 123 int decodedLines = this->codec()->getScanlines(pixels, scaledSubsetH eight, rowBytes);
125 if (decodedLines != scaledSubsetHeight) { 124 if (decodedLines != scaledSubsetHeight) {
126 return SkCodec::kIncompleteInput; 125 return SkCodec::kIncompleteInput;
127 } 126 }
128 return SkCodec::kSuccess; 127 return SkCodec::kSuccess;
129 } 128 }
130 default: 129 default:
131 SkASSERT(false); 130 SkASSERT(false);
132 return SkCodec::kUnimplemented; 131 return SkCodec::kUnimplemented;
133 } 132 }
134 } 133 }
(...skipping 14 matching lines...) Expand all
149 SkISize nativeSize = this->accountForNativeScaling(&sampleSize, &nativeSampl eSize); 148 SkISize nativeSize = this->accountForNativeScaling(&sampleSize, &nativeSampl eSize);
150 149
151 // Check if there is a subset. 150 // Check if there is a subset.
152 SkIRect subset; 151 SkIRect subset;
153 int subsetY = 0; 152 int subsetY = 0;
154 int subsetWidth = nativeSize.width(); 153 int subsetWidth = nativeSize.width();
155 int subsetHeight = nativeSize.height(); 154 int subsetHeight = nativeSize.height();
156 if (options.fSubset) { 155 if (options.fSubset) {
157 // We will need to know about subsetting in the y-dimension in order to use the 156 // We will need to know about subsetting in the y-dimension in order to use the
158 // scanline decoder. 157 // scanline decoder.
159 // Update the subset to account for scaling done by fCodec. 158 // Update the subset to account for scaling done by this->codec().
160 SkIRect* subsetPtr = options.fSubset; 159 SkIRect* subsetPtr = options.fSubset;
161 160
162 // Do the divide ourselves, instead of calling get_scaled_dimension. If 161 // Do the divide ourselves, instead of calling get_scaled_dimension. If
163 // X and Y are 0, they should remain 0, rather than being upgraded to 1 162 // X and Y are 0, they should remain 0, rather than being upgraded to 1
164 // due to being smaller than the sampleSize. 163 // due to being smaller than the sampleSize.
165 const int subsetX = subsetPtr->x() / nativeSampleSize; 164 const int subsetX = subsetPtr->x() / nativeSampleSize;
166 subsetY = subsetPtr->y() / nativeSampleSize; 165 subsetY = subsetPtr->y() / nativeSampleSize;
167 166
168 subsetWidth = get_scaled_dimension(subsetPtr->width(), nativeSampleSize) ; 167 subsetWidth = get_scaled_dimension(subsetPtr->width(), nativeSampleSize) ;
169 subsetHeight = get_scaled_dimension(subsetPtr->height(), nativeSampleSiz e); 168 subsetHeight = get_scaled_dimension(subsetPtr->height(), nativeSampleSiz e);
170 169
171 // The scanline decoder only needs to be aware of subsetting in the x-di mension. 170 // The scanline decoder only needs to be aware of subsetting in the x-di mension.
172 subset.setXYWH(subsetX, 0, subsetWidth, nativeSize.height()); 171 subset.setXYWH(subsetX, 0, subsetWidth, nativeSize.height());
173 sampledOptions.fSubset = ⊂ 172 sampledOptions.fSubset = ⊂
174 } 173 }
175 174
176 // Start the scanline decode. 175 // Start the scanline decode.
177 SkCodec::Result result = fCodec->startScanlineDecode( 176 SkCodec::Result result = this->codec()->startScanlineDecode(
178 info.makeWH(nativeSize.width(), nativeSize.height()), &sampledOption s, 177 info.makeWH(nativeSize.width(), nativeSize.height()), &sampledOption s,
179 options.fColorPtr, options.fColorCount); 178 options.fColorPtr, options.fColorCount);
180 if (SkCodec::kSuccess != result) { 179 if (SkCodec::kSuccess != result) {
181 return result; 180 return result;
182 } 181 }
183 182
184 SkSampler* sampler = fCodec->getSampler(true); 183 SkSampler* sampler = this->codec()->getSampler(true);
185 if (!sampler) { 184 if (!sampler) {
186 return SkCodec::kUnimplemented; 185 return SkCodec::kUnimplemented;
187 } 186 }
188 187
189 // Since we guarantee that output dimensions are always at least one (even i f the sampleSize 188 // Since we guarantee that output dimensions are always at least one (even i f the sampleSize
190 // is greater than a given dimension), the input sampleSize is not always th e sampleSize that 189 // is greater than a given dimension), the input sampleSize is not always th e sampleSize that
191 // we use in practice. 190 // we use in practice.
192 const int sampleX = subsetWidth / info.width(); 191 const int sampleX = subsetWidth / info.width();
193 const int sampleY = subsetHeight / info.height(); 192 const int sampleY = subsetHeight / info.height();
194 if (sampler->setSampleX(sampleX) != info.width()) { 193 if (sampler->setSampleX(sampleX) != info.width()) {
195 return SkCodec::kInvalidScale; 194 return SkCodec::kInvalidScale;
196 } 195 }
197 if (get_scaled_dimension(subsetHeight, sampleY) != info.height()) { 196 if (get_scaled_dimension(subsetHeight, sampleY) != info.height()) {
198 return SkCodec::kInvalidScale; 197 return SkCodec::kInvalidScale;
199 } 198 }
200 199
201 const int samplingOffsetY = get_start_coord(sampleY); 200 const int samplingOffsetY = get_start_coord(sampleY);
202 const int startY = samplingOffsetY + subsetY; 201 const int startY = samplingOffsetY + subsetY;
203 int dstHeight = info.height(); 202 int dstHeight = info.height();
204 switch(fCodec->getScanlineOrder()) { 203 switch(this->codec()->getScanlineOrder()) {
205 case SkCodec::kTopDown_SkScanlineOrder: { 204 case SkCodec::kTopDown_SkScanlineOrder: {
206 if (!fCodec->skipScanlines(startY)) { 205 if (!this->codec()->skipScanlines(startY)) {
207 fCodec->fillIncompleteImage(info, pixels, rowBytes, options.fZer oInitialized, 206 this->codec()->fillIncompleteImage(info, pixels, rowBytes, optio ns.fZeroInitialized,
208 dstHeight, 0); 207 dstHeight, 0);
209 return SkCodec::kIncompleteInput; 208 return SkCodec::kIncompleteInput;
210 } 209 }
211 void* pixelPtr = pixels; 210 void* pixelPtr = pixels;
212 for (int y = 0; y < dstHeight; y++) { 211 for (int y = 0; y < dstHeight; y++) {
213 if (1 != fCodec->getScanlines(pixelPtr, 1, rowBytes)) { 212 if (1 != this->codec()->getScanlines(pixelPtr, 1, rowBytes)) {
214 fCodec->fillIncompleteImage(info, pixels, rowBytes, options. fZeroInitialized, 213 this->codec()->fillIncompleteImage(info, pixels, rowBytes,
215 dstHeight, y + 1); 214 options.fZeroInitialized, dstHeight, y + 1);
216 return SkCodec::kIncompleteInput; 215 return SkCodec::kIncompleteInput;
217 } 216 }
218 if (y < dstHeight - 1) { 217 if (y < dstHeight - 1) {
219 if (!fCodec->skipScanlines(sampleY - 1)) { 218 if (!this->codec()->skipScanlines(sampleY - 1)) {
220 fCodec->fillIncompleteImage(info, pixels, rowBytes, 219 this->codec()->fillIncompleteImage(info, pixels, rowByte s,
221 options.fZeroInitialized, dstHeight, y + 1); 220 options.fZeroInitialized, dstHeight, y + 1);
222 return SkCodec::kIncompleteInput; 221 return SkCodec::kIncompleteInput;
223 } 222 }
224 } 223 }
225 pixelPtr = SkTAddOffset<void>(pixelPtr, rowBytes); 224 pixelPtr = SkTAddOffset<void>(pixelPtr, rowBytes);
226 } 225 }
227 return SkCodec::kSuccess; 226 return SkCodec::kSuccess;
228 } 227 }
229 case SkCodec::kOutOfOrder_SkScanlineOrder: 228 case SkCodec::kOutOfOrder_SkScanlineOrder:
230 case SkCodec::kBottomUp_SkScanlineOrder: { 229 case SkCodec::kBottomUp_SkScanlineOrder: {
231 // Note that these modes do not support subsetting. 230 // Note that these modes do not support subsetting.
232 SkASSERT(0 == subsetY && nativeSize.height() == subsetHeight); 231 SkASSERT(0 == subsetY && nativeSize.height() == subsetHeight);
233 int y; 232 int y;
234 for (y = 0; y < nativeSize.height(); y++) { 233 for (y = 0; y < nativeSize.height(); y++) {
235 int srcY = fCodec->nextScanline(); 234 int srcY = this->codec()->nextScanline();
236 if (is_coord_necessary(srcY, sampleY, dstHeight)) { 235 if (is_coord_necessary(srcY, sampleY, dstHeight)) {
237 void* pixelPtr = SkTAddOffset<void>(pixels, 236 void* pixelPtr = SkTAddOffset<void>(pixels,
238 rowBytes * get_dst_coord(srcY, sampleY)); 237 rowBytes * get_dst_coord(srcY, sampleY));
239 if (1 != fCodec->getScanlines(pixelPtr, 1, rowBytes)) { 238 if (1 != this->codec()->getScanlines(pixelPtr, 1, rowBytes)) {
240 break; 239 break;
241 } 240 }
242 } else { 241 } else {
243 if (!fCodec->skipScanlines(1)) { 242 if (!this->codec()->skipScanlines(1)) {
244 break; 243 break;
245 } 244 }
246 } 245 }
247 } 246 }
248 247
249 if (nativeSize.height() == y) { 248 if (nativeSize.height() == y) {
250 return SkCodec::kSuccess; 249 return SkCodec::kSuccess;
251 } 250 }
252 251
253 // We handle filling uninitialized memory here instead of using fCod ec. 252 // We handle filling uninitialized memory here instead of using this ->codec().
254 // fCodec does not know that we are sampling. 253 // this->codec() does not know that we are sampling.
255 const uint32_t fillValue = fCodec->getFillValue(info.colorType(), in fo.alphaType()); 254 const uint32_t fillValue = this->codec()->getFillValue(info.colorTyp e(),
255 info.alphaType());
256 const SkImageInfo fillInfo = info.makeWH(info.width(), 1); 256 const SkImageInfo fillInfo = info.makeWH(info.width(), 1);
257 for (; y < nativeSize.height(); y++) { 257 for (; y < nativeSize.height(); y++) {
258 int srcY = fCodec->outputScanline(y); 258 int srcY = this->codec()->outputScanline(y);
259 if (!is_coord_necessary(srcY, sampleY, dstHeight)) { 259 if (!is_coord_necessary(srcY, sampleY, dstHeight)) {
260 continue; 260 continue;
261 } 261 }
262 262
263 void* rowPtr = SkTAddOffset<void>(pixels, rowBytes * get_dst_coo rd(srcY, sampleY)); 263 void* rowPtr = SkTAddOffset<void>(pixels, rowBytes * get_dst_coo rd(srcY, sampleY));
264 SkSampler::Fill(fillInfo, rowPtr, rowBytes, fillValue, options.f ZeroInitialized); 264 SkSampler::Fill(fillInfo, rowPtr, rowBytes, fillValue, options.f ZeroInitialized);
265 } 265 }
266 return SkCodec::kIncompleteInput; 266 return SkCodec::kIncompleteInput;
267 } 267 }
268 case SkCodec::kNone_SkScanlineOrder: { 268 case SkCodec::kNone_SkScanlineOrder: {
269 const int linesNeeded = subsetHeight - samplingOffsetY; 269 const int linesNeeded = subsetHeight - samplingOffsetY;
270 SkAutoMalloc storage(linesNeeded * rowBytes); 270 SkAutoMalloc storage(linesNeeded * rowBytes);
271 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); 271 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get());
272 272
273 if (!fCodec->skipScanlines(startY)) { 273 if (!this->codec()->skipScanlines(startY)) {
274 fCodec->fillIncompleteImage(info, pixels, rowBytes, options.fZer oInitialized, 274 this->codec()->fillIncompleteImage(info, pixels, rowBytes, optio ns.fZeroInitialized,
275 dstHeight, 0); 275 dstHeight, 0);
276 return SkCodec::kIncompleteInput; 276 return SkCodec::kIncompleteInput;
277 } 277 }
278 int scanlines = fCodec->getScanlines(storagePtr, linesNeeded, rowByt es); 278 int scanlines = this->codec()->getScanlines(storagePtr, linesNeeded, rowBytes);
279 279
280 for (int y = 0; y < dstHeight; y++) { 280 for (int y = 0; y < dstHeight; y++) {
281 memcpy(pixels, storagePtr, info.minRowBytes()); 281 memcpy(pixels, storagePtr, info.minRowBytes());
282 storagePtr += sampleY * rowBytes; 282 storagePtr += sampleY * rowBytes;
283 pixels = SkTAddOffset<void>(pixels, rowBytes); 283 pixels = SkTAddOffset<void>(pixels, rowBytes);
284 } 284 }
285 285
286 if (scanlines < dstHeight) { 286 if (scanlines < dstHeight) {
287 // fCodec has already handled filling uninitialized memory. 287 // this->codec() has already handled filling uninitialized memor y.
288 return SkCodec::kIncompleteInput; 288 return SkCodec::kIncompleteInput;
289 } 289 }
290 return SkCodec::kSuccess; 290 return SkCodec::kSuccess;
291 } 291 }
292 default: 292 default:
293 SkASSERT(false); 293 SkASSERT(false);
294 return SkCodec::kUnimplemented; 294 return SkCodec::kUnimplemented;
295 } 295 }
296 } 296 }
OLDNEW
« no previous file with comments | « src/codec/SkSampledCodec.h ('k') | src/codec/SkWebpAdapterCodec.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698