Chromium Code Reviews| 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 |