| OLD | NEW |
| 1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | 1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
| 2 /* ***** BEGIN LICENSE BLOCK ***** | 2 /* ***** BEGIN LICENSE BLOCK ***** |
| 3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| 4 * | 4 * |
| 5 * The contents of this file are subject to the Mozilla Public License Version | 5 * The contents of this file are subject to the Mozilla Public License Version |
| 6 * 1.1 (the "License"); you may not use this file except in compliance with | 6 * 1.1 (the "License"); you may not use this file except in compliance with |
| 7 * the License. You may obtain a copy of the License at | 7 * the License. You may obtain a copy of the License at |
| 8 * http://www.mozilla.org/MPL/ | 8 * http://www.mozilla.org/MPL/ |
| 9 * | 9 * |
| 10 * Software distributed under the License is distributed on an "AS IS" basis, | 10 * Software distributed under the License is distributed on an "AS IS" basis, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 5000 Arlington Center Boulevard | 65 5000 Arlington Center Boulevard |
| 66 Columbus, Ohio 43220 | 66 Columbus, Ohio 43220 |
| 67 U. S. A. | 67 U. S. A. |
| 68 | 68 |
| 69 CompuServe Incorporated maintains a mailing list with all those individuals and | 69 CompuServe Incorporated maintains a mailing list with all those individuals and |
| 70 organizations who wish to receive copies of this document when it is corrected | 70 organizations who wish to receive copies of this document when it is corrected |
| 71 or revised. This service is offered free of charge; please provide us with your | 71 or revised. This service is offered free of charge; please provide us with your |
| 72 mailing address. | 72 mailing address. |
| 73 */ | 73 */ |
| 74 | 74 |
| 75 #include "GIFImageReader.h" | 75 #include "SkGifImageReader.h" |
| 76 #include "SkColorPriv.h" | 76 #include "SkColorPriv.h" |
| 77 #include "SkGifCodec.h" | 77 #include "SkGifCodec.h" |
| 78 | 78 |
| 79 #include <algorithm> | 79 #include <algorithm> |
| 80 #include <string.h> | 80 #include <string.h> |
| 81 | 81 |
| 82 | 82 |
| 83 // GETN(n, s) requests at least 'n' bytes available from 'q', at start of state
's'. | 83 // GETN(n, s) requests at least 'n' bytes available from 'q', at start of state
's'. |
| 84 // | 84 // |
| 85 // Note, the hold will never need to be bigger than 256 bytes to gather up in th
e hold, | 85 // Note, the hold will never need to be bigger than 256 bytes to gather up in th
e hold, |
| 86 // as each GIF block (except colormaps) can never be bigger than 256 bytes. | 86 // as each GIF block (except colormaps) can never be bigger than 256 bytes. |
| 87 // Colormaps are directly copied in the resp. global_colormap or dynamically all
ocated local_colormap. | 87 // Colormaps are directly copied in the resp. global_colormap or dynamically all
ocated local_colormap. |
| 88 // So a fixed buffer in GIFImageReader is good enough. | 88 // So a fixed buffer in SkGifImageReader is good enough. |
| 89 // This buffer is only needed to copy left-over data from one GifWrite call to t
he next | 89 // This buffer is only needed to copy left-over data from one GifWrite call to t
he next |
| 90 #define GETN(n, s) \ | 90 #define GETN(n, s) \ |
| 91 do { \ | 91 do { \ |
| 92 m_bytesToConsume = (n); \ | 92 m_bytesToConsume = (n); \ |
| 93 m_state = (s); \ | 93 m_state = (s); \ |
| 94 } while (0) | 94 } while (0) |
| 95 | 95 |
| 96 // Get a 16-bit value stored in little-endian format. | 96 // Get a 16-bit value stored in little-endian format. |
| 97 #define GETINT16(p) ((p)[1]<<8|(p)[0]) | 97 #define GETINT16(p) ((p)[1]<<8|(p)[0]) |
| 98 | 98 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 default: | 191 default: |
| 192 break; | 192 break; |
| 193 } | 193 } |
| 194 } while (irow > (m_frameContext->height() - 1)); | 194 } while (irow > (m_frameContext->height() - 1)); |
| 195 } | 195 } |
| 196 return true; | 196 return true; |
| 197 } | 197 } |
| 198 | 198 |
| 199 // Perform Lempel-Ziv-Welch decoding. | 199 // Perform Lempel-Ziv-Welch decoding. |
| 200 // Returns true if decoding was successful. In this case the block will have bee
n completely consumed and/or rowsRemaining will be 0. | 200 // Returns true if decoding was successful. In this case the block will have bee
n completely consumed and/or rowsRemaining will be 0. |
| 201 // Otherwise, decoding failed; returns false in this case, which will always cau
se the GIFImageReader to set the "decode failed" flag. | 201 // Otherwise, decoding failed; returns false in this case, which will always cau
se the SkGifImageReader to set the "decode failed" flag. |
| 202 bool GIFLZWContext::doLZW(const unsigned char* block, size_t bytesInBlock) | 202 bool GIFLZWContext::doLZW(const unsigned char* block, size_t bytesInBlock) |
| 203 { | 203 { |
| 204 const size_t width = m_frameContext->width(); | 204 const size_t width = m_frameContext->width(); |
| 205 | 205 |
| 206 if (rowIter == rowBuffer.end()) | 206 if (rowIter == rowBuffer.end()) |
| 207 return true; | 207 return true; |
| 208 | 208 |
| 209 for (const unsigned char* ch = block; bytesInBlock-- > 0; ch++) { | 209 for (const unsigned char* ch = block; bytesInBlock-- > 0; ch++) { |
| 210 // Feed the next byte into the decoder's 32-bit input buffer. | 210 // Feed the next byte into the decoder's 32-bit input buffer. |
| 211 datum += ((int) *ch) << bits; | 211 datum += ((int) *ch) << bits; |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 } | 333 } |
| 334 srcColormap += BYTES_PER_COLORMAP_ENTRY; | 334 srcColormap += BYTES_PER_COLORMAP_ENTRY; |
| 335 } | 335 } |
| 336 for (size_t i = m_colors; i < MAX_COLORS; i++) { | 336 for (size_t i = m_colors; i < MAX_COLORS; i++) { |
| 337 colorStorage[i] = SK_ColorTRANSPARENT; | 337 colorStorage[i] = SK_ColorTRANSPARENT; |
| 338 } | 338 } |
| 339 m_table = sk_sp<SkColorTable>(new SkColorTable(colorStorage, MAX_COLORS)); | 339 m_table = sk_sp<SkColorTable>(new SkColorTable(colorStorage, MAX_COLORS)); |
| 340 return m_table; | 340 return m_table; |
| 341 } | 341 } |
| 342 | 342 |
| 343 sk_sp<SkColorTable> GIFImageReader::getColorTable(SkColorType colorType, size_t
index) const { | 343 sk_sp<SkColorTable> SkGifImageReader::getColorTable(SkColorType colorType, size_
t index) const { |
| 344 if (index >= m_frames.size()) { | 344 if (index >= m_frames.size()) { |
| 345 return nullptr; | 345 return nullptr; |
| 346 } | 346 } |
| 347 | 347 |
| 348 const GIFFrameContext* frameContext = m_frames[index].get(); | 348 const GIFFrameContext* frameContext = m_frames[index].get(); |
| 349 const GIFColorMap& localColorMap = frameContext->localColorMap(); | 349 const GIFColorMap& localColorMap = frameContext->localColorMap(); |
| 350 if (localColorMap.isDefined()) { | 350 if (localColorMap.isDefined()) { |
| 351 return localColorMap.buildTable(colorType, frameContext->transparentPixe
l()); | 351 return localColorMap.buildTable(colorType, frameContext->transparentPixe
l()); |
| 352 } | 352 } |
| 353 if (m_globalColorMap.isDefined()) { | 353 if (m_globalColorMap.isDefined()) { |
| 354 return m_globalColorMap.buildTable(colorType, frameContext->transparentP
ixel()); | 354 return m_globalColorMap.buildTable(colorType, frameContext->transparentP
ixel()); |
| 355 } | 355 } |
| 356 return nullptr; | 356 return nullptr; |
| 357 } | 357 } |
| 358 | 358 |
| 359 // Perform decoding for this frame. frameComplete will be true if the entire fra
me is decoded. | 359 // Perform decoding for this frame. frameComplete will be true if the entire fra
me is decoded. |
| 360 // Returns false if a decoding error occurred. This is a fatal error and causes
the GIFImageReader to set the "decode failed" flag. | 360 // Returns false if a decoding error occurred. This is a fatal error and causes
the SkGifImageReader to set the "decode failed" flag. |
| 361 // Otherwise, either not enough data is available to decode further than before,
or the new data has been decoded successfully; returns true in this case. | 361 // Otherwise, either not enough data is available to decode further than before,
or the new data has been decoded successfully; returns true in this case. |
| 362 bool GIFFrameContext::decode(SkGifCodec* client, bool* frameComplete) | 362 bool GIFFrameContext::decode(SkGifCodec* client, bool* frameComplete) |
| 363 { | 363 { |
| 364 *frameComplete = false; | 364 *frameComplete = false; |
| 365 if (!m_lzwContext) { | 365 if (!m_lzwContext) { |
| 366 // Wait for more data to properly initialize GIFLZWContext. | 366 // Wait for more data to properly initialize GIFLZWContext. |
| 367 if (!isDataSizeDefined() || !isHeaderDefined()) | 367 if (!isDataSizeDefined() || !isHeaderDefined()) |
| 368 return true; | 368 return true; |
| 369 | 369 |
| 370 m_lzwContext.reset(new GIFLZWContext(client, this)); | 370 m_lzwContext.reset(new GIFLZWContext(client, this)); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 390 if (isComplete()) { | 390 if (isComplete()) { |
| 391 *frameComplete = true; | 391 *frameComplete = true; |
| 392 m_lzwContext.reset(); | 392 m_lzwContext.reset(); |
| 393 } | 393 } |
| 394 return true; | 394 return true; |
| 395 } | 395 } |
| 396 | 396 |
| 397 // Decode a frame. | 397 // Decode a frame. |
| 398 // This method uses GIFFrameContext:decode() to decode the frame; decoding error
is reported to client as a critical failure. | 398 // This method uses GIFFrameContext:decode() to decode the frame; decoding error
is reported to client as a critical failure. |
| 399 // Return true if decoding has progressed. Return false if an error has occurred
. | 399 // Return true if decoding has progressed. Return false if an error has occurred
. |
| 400 bool GIFImageReader::decode(size_t frameIndex, bool* frameComplete) | 400 bool SkGifImageReader::decode(size_t frameIndex, bool* frameComplete) |
| 401 { | 401 { |
| 402 GIFFrameContext* currentFrame = m_frames[frameIndex].get(); | 402 GIFFrameContext* currentFrame = m_frames[frameIndex].get(); |
| 403 | 403 |
| 404 return currentFrame->decode(m_client, frameComplete); | 404 return currentFrame->decode(m_client, frameComplete); |
| 405 } | 405 } |
| 406 | 406 |
| 407 // Parse incoming GIF data stream into internal data structures. | 407 // Parse incoming GIF data stream into internal data structures. |
| 408 // Return true if parsing has progressed or there is not enough data. | 408 // Return true if parsing has progressed or there is not enough data. |
| 409 // Return false if a fatal error is encountered. | 409 // Return false if a fatal error is encountered. |
| 410 bool GIFImageReader::parse(GIFImageReader::GIFParseQuery query) | 410 bool SkGifImageReader::parse(SkGifImageReader::GIFParseQuery query) |
| 411 { | 411 { |
| 412 if (m_parseCompleted) { | 412 if (m_parseCompleted) { |
| 413 return true; | 413 return true; |
| 414 } | 414 } |
| 415 | 415 |
| 416 // GIFSizeQuery and GIFFrameCountQuery are negative, so this is only meaning
ful when >= 0. | 416 // GIFSizeQuery and GIFFrameCountQuery are negative, so this is only meaning
ful when >= 0. |
| 417 const int lastFrameToParse = (int) query; | 417 const int lastFrameToParse = (int) query; |
| 418 if (lastFrameToParse >= 0 && (int) m_frames.size() > lastFrameToParse | 418 if (lastFrameToParse >= 0 && (int) m_frames.size() > lastFrameToParse |
| 419 && m_frames[lastFrameToParse]->isComplete()) { | 419 && m_frames[lastFrameToParse]->isComplete()) { |
| 420 // We have already parsed this frame. | 420 // We have already parsed this frame. |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 842 GETN(0, GIFDone); | 842 GETN(0, GIFDone); |
| 843 return false; | 843 return false; |
| 844 break; | 844 break; |
| 845 } // switch | 845 } // switch |
| 846 m_streamBuffer.flush(); | 846 m_streamBuffer.flush(); |
| 847 } | 847 } |
| 848 | 848 |
| 849 return true; | 849 return true; |
| 850 } | 850 } |
| 851 | 851 |
| 852 void GIFImageReader::addFrameIfNecessary() | 852 void SkGifImageReader::addFrameIfNecessary() |
| 853 { | 853 { |
| 854 if (m_frames.empty() || m_frames.back()->isComplete()) { | 854 if (m_frames.empty() || m_frames.back()->isComplete()) { |
| 855 const size_t i = m_frames.size(); | 855 const size_t i = m_frames.size(); |
| 856 std::unique_ptr<GIFFrameContext> frame(new GIFFrameContext(i)); | 856 std::unique_ptr<GIFFrameContext> frame(new GIFFrameContext(i)); |
| 857 if (0 == i) { | 857 if (0 == i) { |
| 858 frame->setRequiredFrame(SkCodec::kNone); | 858 frame->setRequiredFrame(SkCodec::kNone); |
| 859 } else { | 859 } else { |
| 860 // FIXME: We could correct these after decoding (i.e. some frames ma
y turn out to be | 860 // FIXME: We could correct these after decoding (i.e. some frames ma
y turn out to be |
| 861 // independent although we did not determine that here). | 861 // independent although we did not determine that here). |
| 862 const GIFFrameContext* prevFrameContext = m_frames[i - 1].get(); | 862 const GIFFrameContext* prevFrameContext = m_frames[i - 1].get(); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 932 rowsRemaining = m_frameContext->height(); | 932 rowsRemaining = m_frameContext->height(); |
| 933 | 933 |
| 934 // Clearing the whole suffix table lets us be more tolerant of bad data. | 934 // Clearing the whole suffix table lets us be more tolerant of bad data. |
| 935 for (int i = 0; i < clearCode; ++i) { | 935 for (int i = 0; i < clearCode; ++i) { |
| 936 suffix[i] = i; | 936 suffix[i] = i; |
| 937 suffixLength[i] = 1; | 937 suffixLength[i] = 1; |
| 938 } | 938 } |
| 939 return true; | 939 return true; |
| 940 } | 940 } |
| 941 | 941 |
| OLD | NEW |