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

Side by Side Diff: third_party/gif/SkGifImageReader.cpp

Issue 2450753003: Fix more namespace conflicts in SkGifImageReader (Closed)
Patch Set: Fix macros Created 4 years, 1 month 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 | « third_party/gif/SkGifImageReader.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
99 // Send the data to the display front-end. 99 // Send the data to the display front-end.
100 bool GIFLZWContext::outputRow(const unsigned char* rowBegin) 100 bool SkGIFLZWContext::outputRow(const unsigned char* rowBegin)
101 { 101 {
102 int drowStart = irow; 102 int drowStart = irow;
103 int drowEnd = irow; 103 int drowEnd = irow;
104 104
105 // Haeberli-inspired hack for interlaced GIFs: Replicate lines while 105 // Haeberli-inspired hack for interlaced GIFs: Replicate lines while
106 // displaying to diminish the "venetian-blind" effect as the image is 106 // displaying to diminish the "venetian-blind" effect as the image is
107 // loaded. Adjust pixel vertical positions to avoid the appearance of the 107 // loaded. Adjust pixel vertical positions to avoid the appearance of the
108 // image crawling up the screen as successive passes are drawn. 108 // image crawling up the screen as successive passes are drawn.
109 if (m_frameContext->progressiveDisplay() && m_frameContext->interlaced() && ipass < 4) { 109 if (m_frameContext->progressiveDisplay() && m_frameContext->interlaced() && ipass < 4) {
110 unsigned rowDup = 0; 110 unsigned rowDup = 0;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 SkGifImageReader 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 SkGIFLZWContext::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;
212 bits += 8; 212 bits += 8;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 259
260 while (code >= clearCode) { 260 while (code >= clearCode) {
261 *--rowIter = suffix[code]; 261 *--rowIter = suffix[code];
262 code = prefix[code]; 262 code = prefix[code];
263 } 263 }
264 264
265 *--rowIter = firstchar = suffix[code]; 265 *--rowIter = firstchar = suffix[code];
266 266
267 // Define a new codeword in the dictionary as long as we've read 267 // Define a new codeword in the dictionary as long as we've read
268 // more than one value from the stream. 268 // more than one value from the stream.
269 if (avail < MAX_DICTIONARY_ENTRIES && oldcode != -1) { 269 if (avail < SK_MAX_DICTIONARY_ENTRIES && oldcode != -1) {
270 prefix[avail] = oldcode; 270 prefix[avail] = oldcode;
271 suffix[avail] = firstchar; 271 suffix[avail] = firstchar;
272 suffixLength[avail] = suffixLength[oldcode] + 1; 272 suffixLength[avail] = suffixLength[oldcode] + 1;
273 ++avail; 273 ++avail;
274 274
275 // If we've used up all the codewords of a given length 275 // If we've used up all the codewords of a given length
276 // increase the length of codewords by one bit, but don't 276 // increase the length of codewords by one bit, but don't
277 // exceed the specified maximum codeword size. 277 // exceed the specified maximum codeword size.
278 if (!(avail & codemask) && avail < MAX_DICTIONARY_ENTRIES) { 278 if (!(avail & codemask) && avail < SK_MAX_DICTIONARY_ENTRIES) {
279 ++codesize; 279 ++codesize;
280 codemask += avail; 280 codemask += avail;
281 } 281 }
282 } 282 }
283 oldcode = tempCode; 283 oldcode = tempCode;
284 rowIter += codeLength; 284 rowIter += codeLength;
285 285
286 // Output as many rows as possible. 286 // Output as many rows as possible.
287 unsigned char* rowBegin = rowBuffer.begin(); 287 unsigned char* rowBegin = rowBuffer.begin();
288 for (; rowBegin + width <= rowIter; rowBegin += width) { 288 for (; rowBegin + width <= rowIter; rowBegin += width) {
289 if (!outputRow(rowBegin)) 289 if (!outputRow(rowBegin))
290 return false; 290 return false;
291 rowsRemaining--; 291 rowsRemaining--;
292 if (!rowsRemaining) 292 if (!rowsRemaining)
293 return true; 293 return true;
294 } 294 }
295 295
296 if (rowBegin != rowBuffer.begin()) { 296 if (rowBegin != rowBuffer.begin()) {
297 // Move the remaining bytes to the beginning of the buffer. 297 // Move the remaining bytes to the beginning of the buffer.
298 const size_t bytesToCopy = rowIter - rowBegin; 298 const size_t bytesToCopy = rowIter - rowBegin;
299 memcpy(&rowBuffer.front(), rowBegin, bytesToCopy); 299 memcpy(&rowBuffer.front(), rowBegin, bytesToCopy);
300 rowIter = rowBuffer.begin() + bytesToCopy; 300 rowIter = rowBuffer.begin() + bytesToCopy;
301 } 301 }
302 } 302 }
303 } 303 }
304 return true; 304 return true;
305 } 305 }
306 306
307 sk_sp<SkColorTable> GIFColorMap::buildTable(SkColorType colorType, size_t transp arentPixel) const 307 sk_sp<SkColorTable> SkGIFColorMap::buildTable(SkColorType colorType, size_t tran sparentPixel) const
308 { 308 {
309 if (!m_isDefined) 309 if (!m_isDefined)
310 return nullptr; 310 return nullptr;
311 311
312 const PackColorProc proc = choose_pack_color_proc(false, colorType); 312 const PackColorProc proc = choose_pack_color_proc(false, colorType);
313 if (m_table) { 313 if (m_table) {
314 if (transparentPixel > (unsigned) m_table->count() 314 if (transparentPixel > (unsigned) m_table->count()
315 || m_table->operator[](transparentPixel) == SK_ColorTRANSPARENT) { 315 || m_table->operator[](transparentPixel) == SK_ColorTRANSPARENT) {
316 if (proc == m_packColorProc) { 316 if (proc == m_packColorProc) {
317 // This SkColorTable has already been built with the same transp arent color and 317 // This SkColorTable has already been built with the same transp arent color and
318 // packing proc. Reuse it. 318 // packing proc. Reuse it.
319 return m_table; 319 return m_table;
320 } 320 }
321 } 321 }
322 } 322 }
323 m_packColorProc = proc; 323 m_packColorProc = proc;
324 324
325 SkASSERT(m_colors <= MAX_COLORS); 325 SkASSERT(m_colors <= SK_MAX_COLORS);
326 const uint8_t* srcColormap = m_rawData->bytes(); 326 const uint8_t* srcColormap = m_rawData->bytes();
327 SkPMColor colorStorage[MAX_COLORS]; 327 SkPMColor colorStorage[SK_MAX_COLORS];
328 for (size_t i = 0; i < m_colors; i++) { 328 for (size_t i = 0; i < m_colors; i++) {
329 if (i == transparentPixel) { 329 if (i == transparentPixel) {
330 colorStorage[i] = SK_ColorTRANSPARENT; 330 colorStorage[i] = SK_ColorTRANSPARENT;
331 } else { 331 } else {
332 colorStorage[i] = proc(255, srcColormap[0], srcColormap[1], srcColor map[2]); 332 colorStorage[i] = proc(255, srcColormap[0], srcColormap[1], srcColor map[2]);
333 } 333 }
334 srcColormap += BYTES_PER_COLORMAP_ENTRY; 334 srcColormap += SK_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 < SK_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, SK_MAX_COLORS)) ;
340 return m_table; 340 return m_table;
341 } 341 }
342 342
343 sk_sp<SkColorTable> SkGifImageReader::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 SkGIFFrameContext* frameContext = m_frames[index].get();
349 const GIFColorMap& localColorMap = frameContext->localColorMap(); 349 const SkGIFColorMap& 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 SkGifImageReader 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 SkGIFFrameContext::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 SkGIFLZWContext.
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 SkGIFLZWContext(client, this));
371 if (!m_lzwContext->prepareToDecode()) { 371 if (!m_lzwContext->prepareToDecode()) {
372 m_lzwContext.reset(); 372 m_lzwContext.reset();
373 return false; 373 return false;
374 } 374 }
375 375
376 m_currentLzwBlock = 0; 376 m_currentLzwBlock = 0;
377 } 377 }
378 378
379 // Some bad GIFs have extra blocks beyond the last row, which we don't want to decode. 379 // Some bad GIFs have extra blocks beyond the last row, which we don't want to decode.
380 while (m_currentLzwBlock < m_lzwBlocks.size() && m_lzwContext->hasRemainingR ows()) { 380 while (m_currentLzwBlock < m_lzwBlocks.size() && m_lzwContext->hasRemainingR ows()) {
381 if (!m_lzwContext->doLZW(reinterpret_cast<const unsigned char*>(m_lzwBlo cks[m_currentLzwBlock]->data()), 381 if (!m_lzwContext->doLZW(reinterpret_cast<const unsigned char*>(m_lzwBlo cks[m_currentLzwBlock]->data()),
382 m_lzwBlo cks[m_currentLzwBlock]->size())) { 382 m_lzwBlo cks[m_currentLzwBlock]->size())) {
383 return false; 383 return false;
384 } 384 }
385 ++m_currentLzwBlock; 385 ++m_currentLzwBlock;
386 } 386 }
387 387
388 // If this frame is data complete then the previous loop must have completel y decoded all LZW blocks. 388 // If this frame is data complete then the previous loop must have completel y decoded all LZW blocks.
389 // There will be no more decoding for this frame so it's time to cleanup. 389 // There will be no more decoding for this frame so it's time to cleanup.
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 SkGIFFrameContext:decode() to decode the frame; decoding err or 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 SkGifImageReader::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 SkGIFFrameContext* 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 SkGifImageReader::parse(SkGifImageReader::GIFParseQuery query) 410 bool SkGifImageReader::parse(SkGifImageReader::SkGIFParseQuery 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 // SkGIFSizeQuery and SkGIFFrameCountQuery are negative, so this is only mea ningful 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.
421 return true; 421 return true;
422 } 422 }
423 423
424 while (true) { 424 while (true) {
425 const size_t bytesBuffered = m_streamBuffer.buffer(m_bytesToConsume); 425 const size_t bytesBuffered = m_streamBuffer.buffer(m_bytesToConsume);
426 if (bytesBuffered < m_bytesToConsume) { 426 if (bytesBuffered < m_bytesToConsume) {
427 // The stream does not yet have enough data. Mark that we need less next time around, 427 // The stream does not yet have enough data. Mark that we need less next time around,
428 // and return. 428 // and return.
429 m_bytesToConsume -= bytesBuffered; 429 m_bytesToConsume -= bytesBuffered;
430 return true; 430 return true;
431 } 431 }
432 432
433 switch (m_state) { 433 switch (m_state) {
434 case GIFLZW: 434 case SkGIFLZW:
435 SkASSERT(!m_frames.empty()); 435 SkASSERT(!m_frames.empty());
436 // FIXME: All this copying might be wasteful for e.g. SkMemoryStream 436 // FIXME: All this copying might be wasteful for e.g. SkMemoryStream
437 m_frames.back()->addLzwBlock(m_streamBuffer.get(), m_streamBuffer.by tesBuffered()); 437 m_frames.back()->addLzwBlock(m_streamBuffer.get(), m_streamBuffer.by tesBuffered());
438 GETN(1, GIFSubBlock); 438 GETN(1, SkGIFSubBlock);
439 break; 439 break;
440 440
441 case GIFLZWStart: { 441 case SkGIFLZWStart: {
442 SkASSERT(!m_frames.empty()); 442 SkASSERT(!m_frames.empty());
443 m_frames.back()->setDataSize(this->getOneByte()); 443 m_frames.back()->setDataSize(this->getOneByte());
444 GETN(1, GIFSubBlock); 444 GETN(1, SkGIFSubBlock);
445 break; 445 break;
446 } 446 }
447 447
448 case GIFType: { 448 case SkGIFType: {
449 const char* currentComponent = m_streamBuffer.get(); 449 const char* currentComponent = m_streamBuffer.get();
450 450
451 // All GIF files begin with "GIF87a" or "GIF89a". 451 // All GIF files begin with "GIF87a" or "GIF89a".
452 if (!memcmp(currentComponent, "GIF89a", 6)) 452 if (!memcmp(currentComponent, "GIF89a", 6))
453 m_version = 89; 453 m_version = 89;
454 else if (!memcmp(currentComponent, "GIF87a", 6)) 454 else if (!memcmp(currentComponent, "GIF87a", 6))
455 m_version = 87; 455 m_version = 87;
456 else { 456 else {
457 // This prevents attempting to continue reading this invalid str eam. 457 // This prevents attempting to continue reading this invalid str eam.
458 GETN(0, GIFDone); 458 GETN(0, SkGIFDone);
459 return false; 459 return false;
460 } 460 }
461 GETN(7, GIFGlobalHeader); 461 GETN(7, SkGIFGlobalHeader);
462 break; 462 break;
463 } 463 }
464 464
465 case GIFGlobalHeader: { 465 case SkGIFGlobalHeader: {
466 const unsigned char* currentComponent = 466 const unsigned char* currentComponent =
467 reinterpret_cast<const unsigned char*>(m_streamBuffer.get()); 467 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
468 468
469 // This is the height and width of the "screen" or frame into which 469 // This is the height and width of the "screen" or frame into which
470 // images are rendered. The individual images can be smaller than 470 // images are rendered. The individual images can be smaller than
471 // the screen size and located with an origin anywhere within the 471 // the screen size and located with an origin anywhere within the
472 // screen. 472 // screen.
473 // Note that we don't inform the client of the size yet, as it might 473 // Note that we don't inform the client of the size yet, as it might
474 // change after we read the first frame's image header. 474 // change after we read the first frame's image header.
475 m_screenWidth = GETINT16(currentComponent); 475 m_screenWidth = GETINT16(currentComponent);
476 m_screenHeight = GETINT16(currentComponent + 2); 476 m_screenHeight = GETINT16(currentComponent + 2);
477 477
478 const size_t globalColorMapColors = 2 << (currentComponent[4] & 0x07 ); 478 const size_t globalColorMapColors = 2 << (currentComponent[4] & 0x07 );
479 479
480 if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* g lobal map */ 480 if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* g lobal map */
481 m_globalColorMap.setNumColors(globalColorMapColors); 481 m_globalColorMap.setNumColors(globalColorMapColors);
482 GETN(BYTES_PER_COLORMAP_ENTRY * globalColorMapColors, GIFGlobalC olormap); 482 GETN(SK_BYTES_PER_COLORMAP_ENTRY * globalColorMapColors, SkGIFGl obalColormap);
483 break; 483 break;
484 } 484 }
485 485
486 GETN(1, GIFImageStart); 486 GETN(1, SkGIFImageStart);
487 break; 487 break;
488 } 488 }
489 489
490 case GIFGlobalColormap: { 490 case SkGIFGlobalColormap: {
491 m_globalColorMap.setRawData(m_streamBuffer.get(), m_streamBuffer.byt esBuffered()); 491 m_globalColorMap.setRawData(m_streamBuffer.get(), m_streamBuffer.byt esBuffered());
492 GETN(1, GIFImageStart); 492 GETN(1, SkGIFImageStart);
493 break; 493 break;
494 } 494 }
495 495
496 case GIFImageStart: { 496 case SkGIFImageStart: {
497 const char currentComponent = m_streamBuffer.get()[0]; 497 const char currentComponent = m_streamBuffer.get()[0];
498 498
499 if (currentComponent == '!') { // extension. 499 if (currentComponent == '!') { // extension.
500 GETN(2, GIFExtension); 500 GETN(2, SkGIFExtension);
501 break; 501 break;
502 } 502 }
503 503
504 if (currentComponent == ',') { // image separator. 504 if (currentComponent == ',') { // image separator.
505 GETN(9, GIFImageHeader); 505 GETN(9, SkGIFImageHeader);
506 break; 506 break;
507 } 507 }
508 508
509 // If we get anything other than ',' (image separator), '!' 509 // If we get anything other than ',' (image separator), '!'
510 // (extension), or ';' (trailer), there is extraneous data 510 // (extension), or ';' (trailer), there is extraneous data
511 // between blocks. The GIF87a spec tells us to keep reading 511 // between blocks. The GIF87a spec tells us to keep reading
512 // until we find an image separator, but GIF89a says such 512 // until we find an image separator, but GIF89a says such
513 // a file is corrupt. We follow Mozilla's implementation and 513 // a file is corrupt. We follow Mozilla's implementation and
514 // proceed as if the file were correctly terminated, so the 514 // proceed as if the file were correctly terminated, so the
515 // GIF will display. 515 // GIF will display.
516 GETN(0, GIFDone); 516 GETN(0, SkGIFDone);
517 break; 517 break;
518 } 518 }
519 519
520 case GIFExtension: { 520 case SkGIFExtension: {
521 const unsigned char* currentComponent = 521 const unsigned char* currentComponent =
522 reinterpret_cast<const unsigned char*>(m_streamBuffer.get()); 522 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
523 523
524 size_t bytesInBlock = currentComponent[1]; 524 size_t bytesInBlock = currentComponent[1];
525 GIFState exceptionState = GIFSkipBlock; 525 SkGIFState exceptionState = SkGIFSkipBlock;
526 526
527 switch (*currentComponent) { 527 switch (*currentComponent) {
528 case 0xf9: 528 case 0xf9:
529 exceptionState = GIFControlExtension;
530 // The GIF spec mandates that the GIFControlExtension header blo ck length is 4 bytes, 529 // The GIF spec mandates that the GIFControlExtension header blo ck length is 4 bytes,
530 exceptionState = SkGIFControlExtension;
531 // and the parser for this block reads 4 bytes, so we must enfor ce that the buffer 531 // and the parser for this block reads 4 bytes, so we must enfor ce that the buffer
532 // contains at least this many bytes. If the GIF specifies a dif ferent length, we 532 // contains at least this many bytes. If the GIF specifies a dif ferent length, we
533 // allow that, so long as it's larger; the additional data will simply be ignored. 533 // allow that, so long as it's larger; the additional data will simply be ignored.
534 bytesInBlock = std::max(bytesInBlock, static_cast<size_t>(4)); 534 bytesInBlock = std::max(bytesInBlock, static_cast<size_t>(4));
535 break; 535 break;
536 536
537 // The GIF spec also specifies the lengths of the following two exte nsions' headers 537 // The GIF spec also specifies the lengths of the following two exte nsions' headers
538 // (as 12 and 11 bytes, respectively). Because we ignore the plain t ext extension entirely 538 // (as 12 and 11 bytes, respectively). Because we ignore the plain t ext extension entirely
539 // and sanity-check the actual length of the application extension h eader before reading it, 539 // and sanity-check the actual length of the application extension h eader before reading it,
540 // we allow GIFs to deviate from these values in either direction. T his is important for 540 // we allow GIFs to deviate from these values in either direction. T his is important for
541 // real-world compatibility, as GIFs in the wild exist with applicat ion extension headers 541 // real-world compatibility, as GIFs in the wild exist with applicat ion extension headers
542 // that are both shorter and longer than 11 bytes. 542 // that are both shorter and longer than 11 bytes.
543 case 0x01: 543 case 0x01:
544 // ignoring plain text extension 544 // ignoring plain text extension
545 break; 545 break;
546 546
547 case 0xff: 547 case 0xff:
548 exceptionState = GIFApplicationExtension; 548 exceptionState = SkGIFApplicationExtension;
549 break; 549 break;
550 550
551 case 0xfe: 551 case 0xfe:
552 exceptionState = GIFConsumeComment; 552 exceptionState = SkGIFConsumeComment;
553 break; 553 break;
554 } 554 }
555 555
556 if (bytesInBlock) 556 if (bytesInBlock)
557 GETN(bytesInBlock, exceptionState); 557 GETN(bytesInBlock, exceptionState);
558 else 558 else
559 GETN(1, GIFImageStart); 559 GETN(1, SkGIFImageStart);
560 break; 560 break;
561 } 561 }
562 562
563 case GIFConsumeBlock: { 563 case SkGIFConsumeBlock: {
564 const unsigned char currentComponent = this->getOneByte(); 564 const unsigned char currentComponent = this->getOneByte();
565 if (!currentComponent) 565 if (!currentComponent)
566 GETN(1, GIFImageStart); 566 GETN(1, SkGIFImageStart);
567 else 567 else
568 GETN(currentComponent, GIFSkipBlock); 568 GETN(currentComponent, SkGIFSkipBlock);
569 break; 569 break;
570 } 570 }
571 571
572 case GIFSkipBlock: { 572 case SkGIFSkipBlock: {
573 GETN(1, GIFConsumeBlock); 573 GETN(1, SkGIFConsumeBlock);
574 break; 574 break;
575 } 575 }
576 576
577 case GIFControlExtension: { 577 case SkGIFControlExtension: {
578 const unsigned char* currentComponent = 578 const unsigned char* currentComponent =
579 reinterpret_cast<const unsigned char*>(m_streamBuffer.get()); 579 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
580 580
581 addFrameIfNecessary(); 581 addFrameIfNecessary();
582 GIFFrameContext* currentFrame = m_frames.back().get(); 582 SkGIFFrameContext* currentFrame = m_frames.back().get();
583 if (*currentComponent & 0x1) 583 if (*currentComponent & 0x1)
584 currentFrame->setTransparentPixel(currentComponent[3]); 584 currentFrame->setTransparentPixel(currentComponent[3]);
585 585
586 // We ignore the "user input" bit. 586 // We ignore the "user input" bit.
587 587
588 // NOTE: This relies on the values in the FrameDisposalMethod enum 588 // NOTE: This relies on the values in the FrameDisposalMethod enum
589 // matching those in the GIF spec! 589 // matching those in the GIF spec!
590 int rawDisposalMethod = ((*currentComponent) >> 2) & 0x7; 590 int rawDisposalMethod = ((*currentComponent) >> 2) & 0x7;
591 switch (rawDisposalMethod) { 591 switch (rawDisposalMethod) {
592 case 1: 592 case 1:
593 case 2: 593 case 2:
594 case 3: 594 case 3:
595 currentFrame->setDisposalMethod((SkCodecAnimation::DisposalMetho d) rawDisposalMethod); 595 currentFrame->setDisposalMethod((SkCodecAnimation::DisposalMetho d) rawDisposalMethod);
596 break; 596 break;
597 case 4: 597 case 4:
598 // Some specs say that disposal method 3 is "overwrite previous" , others that setting 598 // Some specs say that disposal method 3 is "overwrite previous" , others that setting
599 // the third bit of the field (i.e. method 4) is. We map both to the same value. 599 // the third bit of the field (i.e. method 4) is. We map both to the same value.
600 currentFrame->setDisposalMethod(SkCodecAnimation::RestorePreviou s_DisposalMethod); 600 currentFrame->setDisposalMethod(SkCodecAnimation::RestorePreviou s_DisposalMethod);
601 break; 601 break;
602 default: 602 default:
603 // Other values use the default. 603 // Other values use the default.
604 currentFrame->setDisposalMethod(SkCodecAnimation::Keep_DisposalM ethod); 604 currentFrame->setDisposalMethod(SkCodecAnimation::Keep_DisposalM ethod);
605 break; 605 break;
606 } 606 }
607 currentFrame->setDelayTime(GETINT16(currentComponent + 1) * 10); 607 currentFrame->setDelayTime(GETINT16(currentComponent + 1) * 10);
608 GETN(1, GIFConsumeBlock); 608 GETN(1, SkGIFConsumeBlock);
609 break; 609 break;
610 } 610 }
611 611
612 case GIFCommentExtension: { 612 case SkGIFCommentExtension: {
613 const unsigned char currentComponent = this->getOneByte(); 613 const unsigned char currentComponent = this->getOneByte();
614 if (currentComponent) 614 if (currentComponent)
615 GETN(currentComponent, GIFConsumeComment); 615 GETN(currentComponent, SkGIFConsumeComment);
616 else 616 else
617 GETN(1, GIFImageStart); 617 GETN(1, SkGIFImageStart);
618 break; 618 break;
619 } 619 }
620 620
621 case GIFConsumeComment: { 621 case SkGIFConsumeComment: {
622 GETN(1, GIFCommentExtension); 622 GETN(1, SkGIFCommentExtension);
623 break; 623 break;
624 } 624 }
625 625
626 case GIFApplicationExtension: { 626 case SkGIFApplicationExtension: {
627 // Check for netscape application extension. 627 // Check for netscape application extension.
628 if (m_streamBuffer.bytesBuffered() == 11) { 628 if (m_streamBuffer.bytesBuffered() == 11) {
629 const unsigned char* currentComponent = 629 const unsigned char* currentComponent =
630 reinterpret_cast<const unsigned char*>(m_streamBuffer.get()) ; 630 reinterpret_cast<const unsigned char*>(m_streamBuffer.get()) ;
631 631
632 if (!memcmp(currentComponent, "NETSCAPE2.0", 11) || !memcmp(curr entComponent, "ANIMEXTS1.0", 11)) 632 if (!memcmp(currentComponent, "NETSCAPE2.0", 11) || !memcmp(curr entComponent, "ANIMEXTS1.0", 11))
633 GETN(1, GIFNetscapeExtensionBlock); 633 GETN(1, SkGIFNetscapeExtensionBlock);
634 } 634 }
635 635
636 if (m_state != GIFNetscapeExtensionBlock) 636 if (m_state != SkGIFNetscapeExtensionBlock)
637 GETN(1, GIFConsumeBlock); 637 GETN(1, SkGIFConsumeBlock);
638 break; 638 break;
639 } 639 }
640 640
641 // Netscape-specific GIF extension: animation looping. 641 // Netscape-specific GIF extension: animation looping.
642 case GIFNetscapeExtensionBlock: { 642 case SkGIFNetscapeExtensionBlock: {
643 const int currentComponent = this->getOneByte(); 643 const int currentComponent = this->getOneByte();
644 // GIFConsumeNetscapeExtension always reads 3 bytes from the stream; we should at least wait for this amount. 644 // SkGIFConsumeNetscapeExtension always reads 3 bytes from the strea m; we should at least wait for this amount.
645 if (currentComponent) 645 if (currentComponent)
646 GETN(std::max(3, currentComponent), GIFConsumeNetscapeExtension) ; 646 GETN(std::max(3, currentComponent), SkGIFConsumeNetscapeExtensio n);
647 else 647 else
648 GETN(1, GIFImageStart); 648 GETN(1, SkGIFImageStart);
649 break; 649 break;
650 } 650 }
651 651
652 // Parse netscape-specific application extensions 652 // Parse netscape-specific application extensions
653 case GIFConsumeNetscapeExtension: { 653 case SkGIFConsumeNetscapeExtension: {
654 const unsigned char* currentComponent = 654 const unsigned char* currentComponent =
655 reinterpret_cast<const unsigned char*>(m_streamBuffer.get()); 655 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
656 656
657 int netscapeExtension = currentComponent[0] & 7; 657 int netscapeExtension = currentComponent[0] & 7;
658 658
659 // Loop entire animation specified # of times. Only read the loop co unt during the first iteration. 659 // Loop entire animation specified # of times. Only read the loop co unt during the first iteration.
660 if (netscapeExtension == 1) { 660 if (netscapeExtension == 1) {
661 m_loopCount = GETINT16(currentComponent + 1); 661 m_loopCount = GETINT16(currentComponent + 1);
662 662
663 // Zero loop count is infinite animation loop request. 663 // Zero loop count is infinite animation loop request.
664 if (!m_loopCount) 664 if (!m_loopCount)
665 m_loopCount = SkCodecAnimation::kAnimationLoopInfinite; 665 m_loopCount = SkCodecAnimation::kAnimationLoopInfinite;
666 666
667 GETN(1, GIFNetscapeExtensionBlock); 667 GETN(1, SkGIFNetscapeExtensionBlock);
668 } else if (netscapeExtension == 2) { 668 } else if (netscapeExtension == 2) {
669 // Wait for specified # of bytes to enter buffer. 669 // Wait for specified # of bytes to enter buffer.
670 670
671 // Don't do this, this extension doesn't exist (isn't used at al l) 671 // Don't do this, this extension doesn't exist (isn't used at al l)
672 // and doesn't do anything, as our streaming/buffering takes car e of it all... 672 // and doesn't do anything, as our streaming/buffering takes car e of it all...
673 // See: http://semmix.pl/color/exgraf/eeg24.htm 673 // See: http://semmix.pl/color/exgraf/eeg24.htm
674 GETN(1, GIFNetscapeExtensionBlock); 674 GETN(1, SkGIFNetscapeExtensionBlock);
675 } else { 675 } else {
676 // 0,3-7 are yet to be defined netscape extension codes 676 // 0,3-7 are yet to be defined netscape extension codes
677 // This prevents attempting to continue reading this invalid str eam. 677 // This prevents attempting to continue reading this invalid str eam.
678 GETN(0, GIFDone); 678 GETN(0, SkGIFDone);
679 return false; 679 return false;
680 } 680 }
681 break; 681 break;
682 } 682 }
683 683
684 case GIFImageHeader: { 684 case SkGIFImageHeader: {
685 unsigned height, width, xOffset, yOffset; 685 unsigned height, width, xOffset, yOffset;
686 const unsigned char* currentComponent = 686 const unsigned char* currentComponent =
687 reinterpret_cast<const unsigned char*>(m_streamBuffer.get()); 687 reinterpret_cast<const unsigned char*>(m_streamBuffer.get());
688 688
689 /* Get image offsets, with respect to the screen origin */ 689 /* Get image offsets, with respect to the screen origin */
690 xOffset = GETINT16(currentComponent); 690 xOffset = GETINT16(currentComponent);
691 yOffset = GETINT16(currentComponent + 2); 691 yOffset = GETINT16(currentComponent + 2);
692 692
693 /* Get image width and height. */ 693 /* Get image width and height. */
694 width = GETINT16(currentComponent + 4); 694 width = GETINT16(currentComponent + 4);
(...skipping 21 matching lines...) Expand all
716 // We choose to return false early, so we will not create an 716 // We choose to return false early, so we will not create an
717 // SkCodec. 717 // SkCodec.
718 718
719 // Work around more broken GIF files that have zero image width or 719 // Work around more broken GIF files that have zero image width or
720 // height. 720 // height.
721 if (!height || !width) { 721 if (!height || !width) {
722 height = m_screenHeight; 722 height = m_screenHeight;
723 width = m_screenWidth; 723 width = m_screenWidth;
724 if (!height || !width) { 724 if (!height || !width) {
725 // This prevents attempting to continue reading this invalid stream. 725 // This prevents attempting to continue reading this invalid stream.
726 GETN(0, GIFDone); 726 GETN(0, SkGIFDone);
727 return false; 727 return false;
728 } 728 }
729 } 729 }
730 730
731 const bool isLocalColormapDefined = currentComponent[8] & 0x80; 731 const bool isLocalColormapDefined = currentComponent[8] & 0x80;
732 // The three low-order bits of currentComponent[8] specify the bits per pixel. 732 // The three low-order bits of currentComponent[8] specify the bits per pixel.
733 const size_t numColors = 2 << (currentComponent[8] & 0x7); 733 const size_t numColors = 2 << (currentComponent[8] & 0x7);
734 if (currentFrameIsFirstFrame()) { 734 if (currentFrameIsFirstFrame()) {
735 bool hasTransparentPixel; 735 bool hasTransparentPixel;
736 if (m_frames.size() == 0) { 736 if (m_frames.size() == 0) {
(...skipping 24 matching lines...) Expand all
761 m_firstFrameSupportsIndex8 = true; 761 m_firstFrameSupportsIndex8 = true;
762 } else { 762 } else {
763 const bool frameIsSubset = xOffset > 0 || yOffset > 0 763 const bool frameIsSubset = xOffset > 0 || yOffset > 0
764 || xOffset + width < m_screenWidth 764 || xOffset + width < m_screenWidth
765 || yOffset + height < m_screenHeight; 765 || yOffset + height < m_screenHeight;
766 m_firstFrameHasAlpha = frameIsSubset; 766 m_firstFrameHasAlpha = frameIsSubset;
767 m_firstFrameSupportsIndex8 = !frameIsSubset; 767 m_firstFrameSupportsIndex8 = !frameIsSubset;
768 } 768 }
769 } 769 }
770 770
771 if (query == GIFSizeQuery) { 771 if (query == SkGIFSizeQuery) {
772 // The decoder needs to stop, so we return here, before 772 // The decoder needs to stop, so we return here, before
773 // flushing the buffer. Next time through, we'll be in the same 773 // flushing the buffer. Next time through, we'll be in the same
774 // state, requiring the same amount in the buffer. 774 // state, requiring the same amount in the buffer.
775 m_bytesToConsume = 0; 775 m_bytesToConsume = 0;
776 return true; 776 return true;
777 } 777 }
778 778
779 addFrameIfNecessary(); 779 addFrameIfNecessary();
780 GIFFrameContext* currentFrame = m_frames.back().get(); 780 SkGIFFrameContext* currentFrame = m_frames.back().get();
781 781
782 currentFrame->setHeaderDefined(); 782 currentFrame->setHeaderDefined();
783 783
784 currentFrame->setRect(xOffset, yOffset, width, height); 784 currentFrame->setRect(xOffset, yOffset, width, height);
785 currentFrame->setInterlaced(currentComponent[8] & 0x40); 785 currentFrame->setInterlaced(currentComponent[8] & 0x40);
786 786
787 // Overlaying interlaced, transparent GIFs over 787 // Overlaying interlaced, transparent GIFs over
788 // existing image data using the Haeberli display hack 788 // existing image data using the Haeberli display hack
789 // requires saving the underlying image in order to 789 // requires saving the underlying image in order to
790 // avoid jaggies at the transparency edges. We are 790 // avoid jaggies at the transparency edges. We are
791 // unprepared to deal with that, so don't display such 791 // unprepared to deal with that, so don't display such
792 // images progressively. Which means only the first 792 // images progressively. Which means only the first
793 // frame can be progressively displayed. 793 // frame can be progressively displayed.
794 // FIXME: It is possible that a non-transparent frame 794 // FIXME: It is possible that a non-transparent frame
795 // can be interlaced and progressively displayed. 795 // can be interlaced and progressively displayed.
796 currentFrame->setProgressiveDisplay(currentFrameIsFirstFrame()); 796 currentFrame->setProgressiveDisplay(currentFrameIsFirstFrame());
797 797
798 if (isLocalColormapDefined) { 798 if (isLocalColormapDefined) {
799 currentFrame->localColorMap().setNumColors(numColors); 799 currentFrame->localColorMap().setNumColors(numColors);
800 GETN(BYTES_PER_COLORMAP_ENTRY * numColors, GIFImageColormap); 800 GETN(SK_BYTES_PER_COLORMAP_ENTRY * numColors, SkGIFImageColormap );
801 break; 801 break;
802 } 802 }
803 803
804 GETN(1, GIFLZWStart); 804 GETN(1, SkGIFLZWStart);
805 break; 805 break;
806 } 806 }
807 807
808 case GIFImageColormap: { 808 case SkGIFImageColormap: {
809 SkASSERT(!m_frames.empty()); 809 SkASSERT(!m_frames.empty());
810 m_frames.back()->localColorMap().setRawData(m_streamBuffer.get(), m_ streamBuffer.bytesBuffered()); 810 m_frames.back()->localColorMap().setRawData(m_streamBuffer.get(), m_ streamBuffer.bytesBuffered());
811 GETN(1, GIFLZWStart); 811 GETN(1, SkGIFLZWStart);
812 break; 812 break;
813 } 813 }
814 814
815 case GIFSubBlock: { 815 case SkGIFSubBlock: {
816 const size_t bytesInBlock = this->getOneByte(); 816 const size_t bytesInBlock = this->getOneByte();
817 if (bytesInBlock) 817 if (bytesInBlock)
818 GETN(bytesInBlock, GIFLZW); 818 GETN(bytesInBlock, SkGIFLZW);
819 else { 819 else {
820 // Finished parsing one frame; Process next frame. 820 // Finished parsing one frame; Process next frame.
821 SkASSERT(!m_frames.empty()); 821 SkASSERT(!m_frames.empty());
822 // Note that some broken GIF files do not have enough LZW blocks to fully 822 // Note that some broken GIF files do not have enough LZW blocks to fully
823 // decode all rows but we treat it as frame complete. 823 // decode all rows but we treat it as frame complete.
824 m_frames.back()->setComplete(); 824 m_frames.back()->setComplete();
825 GETN(1, GIFImageStart); 825 GETN(1, SkGIFImageStart);
826 if (lastFrameToParse >= 0 && (int) m_frames.size() > lastFrameTo Parse) { 826 if (lastFrameToParse >= 0 && (int) m_frames.size() > lastFrameTo Parse) {
827 m_streamBuffer.flush(); 827 m_streamBuffer.flush();
828 return true; 828 return true;
829 } 829 }
830 } 830 }
831 break; 831 break;
832 } 832 }
833 833
834 case GIFDone: { 834 case SkGIFDone: {
835 m_parseCompleted = true; 835 m_parseCompleted = true;
836 return true; 836 return true;
837 } 837 }
838 838
839 default: 839 default:
840 // We shouldn't ever get here. 840 // We shouldn't ever get here.
841 // This prevents attempting to continue reading this invalid stream. 841 // This prevents attempting to continue reading this invalid stream.
842 GETN(0, GIFDone); 842 GETN(0, SkGIFDone);
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 SkGifImageReader::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<SkGIFFrameContext> frame(new SkGIFFrameContext(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 SkGIFFrameContext* prevFrameContext = m_frames[i - 1].get();
863 switch (prevFrameContext->getDisposalMethod()) { 863 switch (prevFrameContext->getDisposalMethod()) {
864 case SkCodecAnimation::Keep_DisposalMethod: 864 case SkCodecAnimation::Keep_DisposalMethod:
865 frame->setRequiredFrame(i - 1); 865 frame->setRequiredFrame(i - 1);
866 break; 866 break;
867 case SkCodecAnimation::RestorePrevious_DisposalMethod: 867 case SkCodecAnimation::RestorePrevious_DisposalMethod:
868 frame->setRequiredFrame(prevFrameContext->getRequiredFrame() ); 868 frame->setRequiredFrame(prevFrameContext->getRequiredFrame() );
869 break; 869 break;
870 case SkCodecAnimation::RestoreBGColor_DisposalMethod: 870 case SkCodecAnimation::RestoreBGColor_DisposalMethod:
871 // If the prior frame covers the whole image 871 // If the prior frame covers the whole image
872 if (prevFrameContext->frameRect() == SkIRect::MakeWH(m_scree nWidth, 872 if (prevFrameContext->frameRect() == SkIRect::MakeWH(m_scree nWidth,
873 m_scree nHeight) 873 m_scree nHeight)
874 // Or the prior frame was independent 874 // Or the prior frame was independent
875 || prevFrameContext->getRequiredFrame() == SkCodec:: kNone) 875 || prevFrameContext->getRequiredFrame() == SkCodec:: kNone)
876 { 876 {
877 // This frame is independent, since we clear everything 877 // This frame is independent, since we clear everything
878 // prior frame to the BG color 878 // prior frame to the BG color
879 frame->setRequiredFrame(SkCodec::kNone); 879 frame->setRequiredFrame(SkCodec::kNone);
880 } else { 880 } else {
881 frame->setRequiredFrame(i - 1); 881 frame->setRequiredFrame(i - 1);
882 } 882 }
883 break; 883 break;
884 } 884 }
885 } 885 }
886 m_frames.push_back(std::move(frame)); 886 m_frames.push_back(std::move(frame));
887 } 887 }
888 } 888 }
889 889
890 // FIXME: Move this method to close to doLZW(). 890 // FIXME: Move this method to close to doLZW().
891 bool GIFLZWContext::prepareToDecode() 891 bool SkGIFLZWContext::prepareToDecode()
892 { 892 {
893 SkASSERT(m_frameContext->isDataSizeDefined() && m_frameContext->isHeaderDefi ned()); 893 SkASSERT(m_frameContext->isDataSizeDefined() && m_frameContext->isHeaderDefi ned());
894 894
895 // Since we use a codesize of 1 more than the datasize, we need to ensure 895 // Since we use a codesize of 1 more than the datasize, we need to ensure
896 // that our datasize is strictly less than the MAX_DICTIONARY_ENTRY_BITS. 896 // that our datasize is strictly less than the SK_MAX_DICTIONARY_ENTRY_BITS.
897 if (m_frameContext->dataSize() >= MAX_DICTIONARY_ENTRY_BITS) 897 if (m_frameContext->dataSize() >= SK_MAX_DICTIONARY_ENTRY_BITS)
898 return false; 898 return false;
899 clearCode = 1 << m_frameContext->dataSize(); 899 clearCode = 1 << m_frameContext->dataSize();
900 avail = clearCode + 2; 900 avail = clearCode + 2;
901 oldcode = -1; 901 oldcode = -1;
902 codesize = m_frameContext->dataSize() + 1; 902 codesize = m_frameContext->dataSize() + 1;
903 codemask = (1 << codesize) - 1; 903 codemask = (1 << codesize) - 1;
904 datum = bits = 0; 904 datum = bits = 0;
905 ipass = m_frameContext->interlaced() ? 1 : 0; 905 ipass = m_frameContext->interlaced() ? 1 : 0;
906 irow = 0; 906 irow = 0;
907 907
908 // We want to know the longest sequence encodable by a dictionary with 908 // We want to know the longest sequence encodable by a dictionary with
909 // MAX_DICTIONARY_ENTRIES entries. If we ignore the need to encode the base 909 // SK_MAX_DICTIONARY_ENTRIES entries. If we ignore the need to encode the ba se
910 // values themselves at the beginning of the dictionary, as well as the need 910 // values themselves at the beginning of the dictionary, as well as the need
911 // for a clear code or a termination code, we could use every entry to 911 // for a clear code or a termination code, we could use every entry to
912 // encode a series of multiple values. If the input value stream looked 912 // encode a series of multiple values. If the input value stream looked
913 // like "AAAAA..." (a long string of just one value), the first dictionary 913 // like "AAAAA..." (a long string of just one value), the first dictionary
914 // entry would encode AA, the next AAA, the next AAAA, and so forth. Thus 914 // entry would encode AA, the next AAA, the next AAAA, and so forth. Thus
915 // the longest sequence would be MAX_DICTIONARY_ENTRIES + 1 values. 915 // the longest sequence would be SK_MAX_DICTIONARY_ENTRIES + 1 values.
916 // 916 //
917 // However, we have to account for reserved entries. The first |datasize| 917 // However, we have to account for reserved entries. The first |datasize|
918 // bits are reserved for the base values, and the next two entries are 918 // bits are reserved for the base values, and the next two entries are
919 // reserved for the clear code and termination code. In theory a GIF can 919 // reserved for the clear code and termination code. In theory a GIF can
920 // set the datasize to 0, meaning we have just two reserved entries, making 920 // set the datasize to 0, meaning we have just two reserved entries, making
921 // the longest sequence (MAX_DICTIONARY_ENTIRES + 1) - 2 values long. Since 921 // the longest sequence (SK_MAX_DICTIONARY_ENTIRES + 1) - 2 values long. Sin ce
922 // each value is a byte, this is also the number of bytes in the longest 922 // each value is a byte, this is also the number of bytes in the longest
923 // encodable sequence. 923 // encodable sequence.
924 const size_t maxBytes = MAX_DICTIONARY_ENTRIES - 1; 924 const size_t maxBytes = SK_MAX_DICTIONARY_ENTRIES - 1;
925 925
926 // Now allocate the output buffer. We decode directly into this buffer 926 // Now allocate the output buffer. We decode directly into this buffer
927 // until we have at least one row worth of data, then call outputRow(). 927 // until we have at least one row worth of data, then call outputRow().
928 // This means worst case we may have (row width - 1) bytes in the buffer 928 // This means worst case we may have (row width - 1) bytes in the buffer
929 // and then decode a sequence |maxBytes| long to append. 929 // and then decode a sequence |maxBytes| long to append.
930 rowBuffer.reset(m_frameContext->width() - 1 + maxBytes); 930 rowBuffer.reset(m_frameContext->width() - 1 + maxBytes);
931 rowIter = rowBuffer.begin(); 931 rowIter = rowBuffer.begin();
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
OLDNEW
« no previous file with comments | « third_party/gif/SkGifImageReader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698