OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2010, The Android Open Source Project | 2 * Copyright 2010, The Android Open Source Project |
3 * | 3 * |
4 * Licensed under the Apache License, Version 2.0 (the "License"); | 4 * Licensed under the Apache License, Version 2.0 (the "License"); |
5 * you may not use this file except in compliance with the License. | 5 * you may not use this file except in compliance with the License. |
6 * You may obtain a copy of the License at | 6 * You may obtain a copy of the License at |
7 * | 7 * |
8 * http://www.apache.org/licenses/LICENSE-2.0 | 8 * http://www.apache.org/licenses/LICENSE-2.0 |
9 * | 9 * |
10 * Unless required by applicable law or agreed to in writing, software | 10 * Unless required by applicable law or agreed to in writing, software |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
51 | 51 |
52 // Define VP8 I/O on top of Skia stream | 52 // Define VP8 I/O on top of Skia stream |
53 | 53 |
54 ////////////////////////////////////////////////////////////////////////// | 54 ////////////////////////////////////////////////////////////////////////// |
55 ////////////////////////////////////////////////////////////////////////// | 55 ////////////////////////////////////////////////////////////////////////// |
56 | 56 |
57 static const size_t WEBP_VP8_HEADER_SIZE = 64; | 57 static const size_t WEBP_VP8_HEADER_SIZE = 64; |
58 static const size_t WEBP_IDECODE_BUFFER_SZ = (1 << 16); | 58 static const size_t WEBP_IDECODE_BUFFER_SZ = (1 << 16); |
59 | 59 |
60 // Parse headers of RIFF container, and check for valid Webp (VP8) content. | 60 // Parse headers of RIFF container, and check for valid Webp (VP8) content. |
61 static bool webp_parse_header(SkStream* stream, int* width, int* height, int* al pha) { | 61 static bool webp_parse_header(SkStreamRewindable* stream, int* width, int* heigh t, int* alpha) { |
62 unsigned char buffer[WEBP_VP8_HEADER_SIZE]; | 62 unsigned char buffer[WEBP_VP8_HEADER_SIZE]; |
63 size_t bytesToRead = WEBP_VP8_HEADER_SIZE; | 63 size_t bytesToRead = WEBP_VP8_HEADER_SIZE; |
64 size_t totalBytesRead = 0; | 64 size_t totalBytesRead = 0; |
65 do { | 65 do { |
66 unsigned char* dst = buffer + totalBytesRead; | 66 unsigned char* dst = buffer + totalBytesRead; |
67 const size_t bytesRead = stream->read(dst, bytesToRead); | 67 const size_t bytesRead = stream->read(dst, bytesToRead); |
68 if (0 == bytesRead) { | 68 if (0 == bytesRead) { |
69 // Could not read any bytes. Check to see if we are at the end (exit | 69 // Could not read any bytes. Check to see if we are at the end (exit |
70 // condition), and continue reading if not. Important for streams | 70 // condition), and continue reading if not. Important for streams |
71 // that do not have all the data ready. | 71 // that do not have all the data ready. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
110 } | 110 } |
111 virtual ~SkWEBPImageDecoder() { | 111 virtual ~SkWEBPImageDecoder() { |
112 SkSafeUnref(fInputStream); | 112 SkSafeUnref(fInputStream); |
113 } | 113 } |
114 | 114 |
115 virtual Format getFormat() const SK_OVERRIDE { | 115 virtual Format getFormat() const SK_OVERRIDE { |
116 return kWEBP_Format; | 116 return kWEBP_Format; |
117 } | 117 } |
118 | 118 |
119 protected: | 119 protected: |
120 virtual bool onBuildTileIndex(SkStream *stream, int *width, int *height) SK_ OVERRIDE; | 120 virtual bool onBuildTileIndex(SkStreamRewindable *stream, int *width, int *h eight) SK_OVERRIDE; |
121 virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& rect) SK_OVERRI DE; | 121 virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& rect) SK_OVERRI DE; |
122 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; | 122 virtual bool onDecode(SkStreamRewindable* stream, SkBitmap* bm, Mode) SK_OVE RRIDE; |
123 | 123 |
124 private: | 124 private: |
125 /** | 125 /** |
126 * Called when determining the output config to request to webp. | 126 * Called when determining the output config to request to webp. |
127 * If the image does not have alpha, there is no need to premultiply. | 127 * If the image does not have alpha, there is no need to premultiply. |
128 * If the caller wants unpremultiplied colors, that is respected. | 128 * If the caller wants unpremultiplied colors, that is respected. |
129 */ | 129 */ |
130 bool shouldPremultiply() const { | 130 bool shouldPremultiply() const { |
131 return SkToBool(fHasAlpha) && !this->getRequireUnpremultipliedColors(); | 131 return SkToBool(fHasAlpha) && !this->getRequireUnpremultipliedColors(); |
132 } | 132 } |
133 | 133 |
134 bool setDecodeConfig(SkBitmap* decodedBitmap, int width, int height); | 134 bool setDecodeConfig(SkBitmap* decodedBitmap, int width, int height); |
135 | 135 |
136 SkStream* fInputStream; | 136 SkStreamRewindable* fInputStream; |
137 int fOrigWidth; | 137 int fOrigWidth; |
138 int fOrigHeight; | 138 int fOrigHeight; |
139 int fHasAlpha; | 139 int fHasAlpha; |
bungeman-skia
2013/09/19 16:15:49
Vertical aligning declarations (aka table style de
scroggo
2013/09/25 20:25:09
I could have sworn this was in our style guide. It
| |
140 | 140 |
141 typedef SkImageDecoder INHERITED; | 141 typedef SkImageDecoder INHERITED; |
142 }; | 142 }; |
143 | 143 |
144 ////////////////////////////////////////////////////////////////////////// | 144 ////////////////////////////////////////////////////////////////////////// |
145 | 145 |
146 #ifdef TIME_DECODE | 146 #ifdef TIME_DECODE |
147 | 147 |
148 #include "SkTime.h" | 148 #include "SkTime.h" |
149 | 149 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
185 mode = premultiply ? MODE_rgbA_4444 : MODE_RGBA_4444; | 185 mode = premultiply ? MODE_rgbA_4444 : MODE_RGBA_4444; |
186 } else if (config == SkBitmap::kRGB_565_Config) { | 186 } else if (config == SkBitmap::kRGB_565_Config) { |
187 mode = MODE_RGB_565; | 187 mode = MODE_RGB_565; |
188 } | 188 } |
189 SkASSERT(MODE_LAST != mode); | 189 SkASSERT(MODE_LAST != mode); |
190 return mode; | 190 return mode; |
191 } | 191 } |
192 | 192 |
193 // Incremental WebP image decoding. Reads input buffer of 64K size iteratively | 193 // Incremental WebP image decoding. Reads input buffer of 64K size iteratively |
194 // and decodes this block to appropriate color-space as per config object. | 194 // and decodes this block to appropriate color-space as per config object. |
195 static bool webp_idecode(SkStream* stream, WebPDecoderConfig* config) { | 195 static bool webp_idecode(SkStreamRewindable* stream, WebPDecoderConfig* config) { |
196 WebPIDecoder* idec = WebPIDecode(NULL, 0, config); | 196 WebPIDecoder* idec = WebPIDecode(NULL, 0, config); |
197 if (NULL == idec) { | 197 if (NULL == idec) { |
198 WebPFreeDecBuffer(&config->output); | 198 WebPFreeDecBuffer(&config->output); |
199 return false; | 199 return false; |
200 } | 200 } |
201 | 201 |
202 if (!stream->rewind()) { | 202 if (!stream->rewind()) { |
203 SkDebugf("Failed to rewind webp stream!"); | 203 SkDebugf("Failed to rewind webp stream!"); |
204 return false; | 204 return false; |
205 } | 205 } |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
300 return false; | 300 return false; |
301 } | 301 } |
302 | 302 |
303 decodedBitmap->setConfig(config, width, height, 0); | 303 decodedBitmap->setConfig(config, width, height, 0); |
304 | 304 |
305 decodedBitmap->setIsOpaque(!fHasAlpha); | 305 decodedBitmap->setIsOpaque(!fHasAlpha); |
306 | 306 |
307 return true; | 307 return true; |
308 } | 308 } |
309 | 309 |
310 bool SkWEBPImageDecoder::onBuildTileIndex(SkStream* stream, | 310 bool SkWEBPImageDecoder::onBuildTileIndex(SkStreamRewindable* stream, |
311 int *width, int *height) { | 311 int *width, int *height) { |
312 int origWidth, origHeight, hasAlpha; | 312 int origWidth, origHeight, hasAlpha; |
313 if (!webp_parse_header(stream, &origWidth, &origHeight, &hasAlpha)) { | 313 if (!webp_parse_header(stream, &origWidth, &origHeight, &hasAlpha)) { |
314 return false; | 314 return false; |
315 } | 315 } |
316 | 316 |
317 if (!stream->rewind()) { | 317 if (!stream->rewind()) { |
318 SkDebugf("Failed to rewind webp stream!"); | 318 SkDebugf("Failed to rewind webp stream!"); |
319 return false; | 319 return false; |
320 } | 320 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
400 return false; | 400 return false; |
401 } | 401 } |
402 | 402 |
403 if (!directDecode) { | 403 if (!directDecode) { |
404 cropBitmap(decodedBitmap, bitmap, sampleSize, region.x(), region.y(), | 404 cropBitmap(decodedBitmap, bitmap, sampleSize, region.x(), region.y(), |
405 region.width(), region.height(), rect.x(), rect.y()); | 405 region.width(), region.height(), rect.x(), rect.y()); |
406 } | 406 } |
407 return true; | 407 return true; |
408 } | 408 } |
409 | 409 |
410 bool SkWEBPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, | 410 bool SkWEBPImageDecoder::onDecode(SkStreamRewindable* stream, SkBitmap* decodedB itmap, |
411 Mode mode) { | 411 Mode mode) { |
412 #ifdef TIME_DECODE | 412 #ifdef TIME_DECODE |
413 AutoTimeMillis atm("WEBP Decode"); | 413 AutoTimeMillis atm("WEBP Decode"); |
414 #endif | 414 #endif |
415 | 415 |
416 int origWidth, origHeight, hasAlpha; | 416 int origWidth, origHeight, hasAlpha; |
417 if (!webp_parse_header(stream, &origWidth, &origHeight, &hasAlpha)) { | 417 if (!webp_parse_header(stream, &origWidth, &origHeight, &hasAlpha)) { |
418 return false; | 418 return false; |
419 } | 419 } |
420 this->fHasAlpha = hasAlpha; | 420 this->fHasAlpha = hasAlpha; |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
577 } | 577 } |
578 | 578 |
579 | 579 |
580 /////////////////////////////////////////////////////////////////////////////// | 580 /////////////////////////////////////////////////////////////////////////////// |
581 DEFINE_DECODER_CREATOR(WEBPImageDecoder); | 581 DEFINE_DECODER_CREATOR(WEBPImageDecoder); |
582 DEFINE_ENCODER_CREATOR(WEBPImageEncoder); | 582 DEFINE_ENCODER_CREATOR(WEBPImageEncoder); |
583 /////////////////////////////////////////////////////////////////////////////// | 583 /////////////////////////////////////////////////////////////////////////////// |
584 | 584 |
585 #include "SkTRegistry.h" | 585 #include "SkTRegistry.h" |
586 | 586 |
587 static SkImageDecoder* sk_libwebp_dfactory(SkStream* stream) { | 587 static SkImageDecoder* sk_libwebp_dfactory(SkStreamRewindable* stream) { |
588 int width, height, hasAlpha; | 588 int width, height, hasAlpha; |
589 if (!webp_parse_header(stream, &width, &height, &hasAlpha)) { | 589 if (!webp_parse_header(stream, &width, &height, &hasAlpha)) { |
590 return NULL; | 590 return NULL; |
591 } | 591 } |
592 | 592 |
593 // Magic matches, call decoder | 593 // Magic matches, call decoder |
594 return SkNEW(SkWEBPImageDecoder); | 594 return SkNEW(SkWEBPImageDecoder); |
595 } | 595 } |
596 | 596 |
597 static SkImageDecoder::Format get_format_webp(SkStream* stream) { | 597 static SkImageDecoder::Format get_format_webp(SkStreamRewindable* stream) { |
598 int width, height, hasAlpha; | 598 int width, height, hasAlpha; |
599 if (webp_parse_header(stream, &width, &height, &hasAlpha)) { | 599 if (webp_parse_header(stream, &width, &height, &hasAlpha)) { |
600 return SkImageDecoder::kWEBP_Format; | 600 return SkImageDecoder::kWEBP_Format; |
601 } | 601 } |
602 return SkImageDecoder::kUnknown_Format; | 602 return SkImageDecoder::kUnknown_Format; |
603 } | 603 } |
604 | 604 |
605 static SkImageEncoder* sk_libwebp_efactory(SkImageEncoder::Type t) { | 605 static SkImageEncoder* sk_libwebp_efactory(SkImageEncoder::Type t) { |
606 return (SkImageEncoder::kWEBP_Type == t) ? SkNEW(SkWEBPImageEncoder) : NUL L; | 606 return (SkImageEncoder::kWEBP_Type == t) ? SkNEW(SkWEBPImageEncoder) : NUL L; |
607 } | 607 } |
608 | 608 |
609 static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(sk_libwebp_dfactory); | 609 static SkTRegistry<SkImageDecoder*, SkStreamRewindable*> gDReg(sk_libwebp_dfacto ry); |
610 static SkTRegistry<SkImageDecoder::Format, SkStream*> gFormatReg(get_format_webp ); | 610 static SkTRegistry<SkImageDecoder::Format, SkStreamRewindable*> gFormatReg(get_f ormat_webp); |
611 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libwebp_efact ory); | 611 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libwebp_efact ory); |
OLD | NEW |