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

Side by Side Diff: third_party/WebKit/Source/platform/image-decoders/gif/GIFImageReader.cpp

Issue 2565323003: Move gif image decoder to SkCodec (Closed)
Patch Set: Explicitly specify move ctor / assignment until required patch lands. Created 3 years, 4 months 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/WebKit/Source/platform/image-decoders/gif/GIFImageReader.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
(Empty)
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
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
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is mozilla.org code.
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 * Chris Saari <saari@netscape.com>
24 * Apple Computer
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
37 *
38 * ***** END LICENSE BLOCK ***** */
39
40 /*
41 The Graphics Interchange Format(c) is the copyright property of CompuServe
42 Incorporated. Only CompuServe Incorporated is authorized to define, redefine,
43 enhance, alter, modify or change in any way the definition of the format.
44
45 CompuServe Incorporated hereby grants a limited, non-exclusive, royalty-free
46 license for the use of the Graphics Interchange Format(sm) in computer
47 software; computer software utilizing GIF(sm) must acknowledge ownership of the
48 Graphics Interchange Format and its Service Mark by CompuServe Incorporated, in
49 User and Technical Documentation. Computer software utilizing GIF, which is
50 distributed or may be distributed without User or Technical Documentation must
51 display to the screen or printer a message acknowledging ownership of the
52 Graphics Interchange Format and the Service Mark by CompuServe Incorporated; in
53 this case, the acknowledgement may be displayed in an opening screen or leading
54 banner, or a closing screen or trailing banner. A message such as the following
55 may be used:
56
57 "The Graphics Interchange Format(c) is the Copyright property of
58 CompuServe Incorporated. GIF(sm) is a Service Mark property of
59 CompuServe Incorporated."
60
61 For further information, please contact :
62
63 CompuServe Incorporated
64 Graphics Technology Department
65 5000 Arlington Center Boulevard
66 Columbus, Ohio 43220
67 U. S. A.
68
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
71 or revised. This service is offered free of charge; please provide us with your
72 mailing address.
73 */
74
75 #include "platform/image-decoders/gif/GIFImageReader.h"
76
77 #include <string.h>
78 #include "platform/image-decoders/FastSharedBufferReader.h"
79 #include "platform/wtf/PtrUtil.h"
80
81 namespace blink {
82
83 namespace {
84
85 static constexpr unsigned kMaxColors = 256u;
86 static constexpr int kBytesPerColormapEntry = 3;
87
88 } // namespace
89
90 // GETN(n, s) requests at least 'n' bytes available from 'q', at start of state
91 // 's'.
92 //
93 // Note: the hold will never need to be bigger than 256 bytes, as each GIF block
94 // (except colormaps) can never be bigger than 256 bytes. Colormaps are directly
95 // copied in the resp. global_colormap or dynamically allocated local_colormap,
96 // so a fixed buffer in GIFImageReader is good enough. This buffer is only
97 // needed to copy left-over data from one GifWrite call to the next.
98 #define GETN(n, s) \
99 do { \
100 bytes_to_consume_ = (n); \
101 state_ = (s); \
102 } while (0)
103
104 // Get a 16-bit value stored in little-endian format.
105 #define GETINT16(p) ((p)[1] << 8 | (p)[0])
106
107 // Send the data to the display front-end.
108 bool GIFLZWContext::OutputRow(GIFRow::const_iterator row_begin) {
109 int drow_start = irow;
110 int drow_end = irow;
111
112 // Haeberli-inspired hack for interlaced GIFs: Replicate lines while
113 // displaying to diminish the "venetian-blind" effect as the image is
114 // loaded. Adjust pixel vertical positions to avoid the appearance of the
115 // image crawling up the screen as successive passes are drawn.
116 if (frame_context_->ProgressiveDisplay() && frame_context_->Interlaced() &&
117 ipass < 4) {
118 unsigned row_dup = 0;
119 unsigned row_shift = 0;
120
121 switch (ipass) {
122 case 1:
123 row_dup = 7;
124 row_shift = 3;
125 break;
126 case 2:
127 row_dup = 3;
128 row_shift = 1;
129 break;
130 case 3:
131 row_dup = 1;
132 row_shift = 0;
133 break;
134 default:
135 break;
136 }
137
138 drow_start -= row_shift;
139 drow_end = drow_start + row_dup;
140
141 // Extend if bottom edge isn't covered because of the shift upward.
142 if (((frame_context_->Height() - 1) - drow_end) <= row_shift)
143 drow_end = frame_context_->Height() - 1;
144
145 // Clamp first and last rows to upper and lower edge of image.
146 if (drow_start < 0)
147 drow_start = 0;
148
149 if ((unsigned)drow_end >= frame_context_->Height())
150 drow_end = frame_context_->Height() - 1;
151 }
152
153 // Protect against too much image data.
154 if ((unsigned)drow_start >= frame_context_->Height())
155 return true;
156
157 // CALLBACK: Let the client know we have decoded a row.
158 if (!client_->HaveDecodedRow(frame_context_->FrameId(), row_begin,
159 frame_context_->Width(), drow_start,
160 drow_end - drow_start + 1,
161 frame_context_->ProgressiveDisplay() &&
162 frame_context_->Interlaced() && ipass > 1))
163 return false;
164
165 if (!frame_context_->Interlaced())
166 irow++;
167 else {
168 do {
169 switch (ipass) {
170 case 1:
171 irow += 8;
172 if (irow >= frame_context_->Height()) {
173 ipass++;
174 irow = 4;
175 }
176 break;
177
178 case 2:
179 irow += 8;
180 if (irow >= frame_context_->Height()) {
181 ipass++;
182 irow = 2;
183 }
184 break;
185
186 case 3:
187 irow += 4;
188 if (irow >= frame_context_->Height()) {
189 ipass++;
190 irow = 1;
191 }
192 break;
193
194 case 4:
195 irow += 2;
196 if (irow >= frame_context_->Height()) {
197 ipass++;
198 irow = 0;
199 }
200 break;
201
202 default:
203 break;
204 }
205 } while (irow > (frame_context_->Height() - 1));
206 }
207 return true;
208 }
209
210 // Performs Lempel-Ziv-Welch decoding. Returns whether decoding was successful.
211 // If successful, the block will have been completely consumed and/or
212 // rowsRemaining will be 0.
213 bool GIFLZWContext::DoLZW(const unsigned char* block, size_t bytes_in_block) {
214 const size_t width = frame_context_->Width();
215
216 if (row_iter == row_buffer.end())
217 return true;
218
219 for (const unsigned char* ch = block; bytes_in_block-- > 0; ch++) {
220 // Feed the next byte into the decoder's 32-bit input buffer.
221 datum += ((int)*ch) << bits;
222 bits += 8;
223
224 // Check for underflow of decoder's 32-bit input buffer.
225 while (bits >= codesize) {
226 // Get the leading variable-length symbol from the data stream.
227 int code = datum & codemask;
228 datum >>= codesize;
229 bits -= codesize;
230
231 // Reset the dictionary to its original state, if requested.
232 if (code == clear_code) {
233 codesize = frame_context_->DataSize() + 1;
234 codemask = (1 << codesize) - 1;
235 avail = clear_code + 2;
236 oldcode = -1;
237 continue;
238 }
239
240 // Check for explicit end-of-stream code.
241 if (code == (clear_code + 1)) {
242 // end-of-stream should only appear after all image data.
243 if (!rows_remaining)
244 return true;
245 return false;
246 }
247
248 const int temp_code = code;
249 unsigned short code_length = 0;
250 if (code < avail) {
251 // This is a pre-existing code, so we already know what it
252 // encodes.
253 code_length = suffix_length[code];
254 row_iter += code_length;
255 } else if (code == avail && oldcode != -1) {
256 // This is a new code just being added to the dictionary.
257 // It must encode the contents of the previous code, plus
258 // the first character of the previous code again.
259 code_length = suffix_length[oldcode] + 1;
260 row_iter += code_length;
261 *--row_iter = firstchar;
262 code = oldcode;
263 } else {
264 // This is an invalid code. The dictionary is just initialized
265 // and the code is incomplete. We don't know how to handle
266 // this case.
267 return false;
268 }
269
270 while (code >= clear_code) {
271 *--row_iter = suffix[code];
272 code = prefix[code];
273 }
274
275 *--row_iter = firstchar = suffix[code];
276
277 // Define a new codeword in the dictionary as long as we've read
278 // more than one value from the stream.
279 if (avail < kMaxDictionaryEntries && oldcode != -1) {
280 prefix[avail] = oldcode;
281 suffix[avail] = firstchar;
282 suffix_length[avail] = suffix_length[oldcode] + 1;
283 ++avail;
284
285 // If we've used up all the codewords of a given length
286 // increase the length of codewords by one bit, but don't
287 // exceed the specified maximum codeword size.
288 if (!(avail & codemask) && avail < kMaxDictionaryEntries) {
289 ++codesize;
290 codemask += avail;
291 }
292 }
293 oldcode = temp_code;
294 row_iter += code_length;
295
296 // Output as many rows as possible.
297 GIFRow::iterator row_begin = row_buffer.begin();
298 for (; row_begin + width <= row_iter; row_begin += width) {
299 if (!OutputRow(row_begin))
300 return false;
301 rows_remaining--;
302 if (!rows_remaining)
303 return true;
304 }
305
306 if (row_begin != row_buffer.begin()) {
307 // Move the remaining bytes to the beginning of the buffer.
308 const size_t bytes_to_copy = row_iter - row_begin;
309 memcpy(row_buffer.begin(), row_begin, bytes_to_copy);
310 row_iter = row_buffer.begin() + bytes_to_copy;
311 }
312 }
313 }
314 return true;
315 }
316
317 void GIFColorMap::BuildTable(FastSharedBufferReader* reader) {
318 if (!is_defined_ || !table_.IsEmpty())
319 return;
320
321 CHECK_LE(position_ + colors_ * kBytesPerColormapEntry, reader->size());
322 DCHECK_LE(colors_, kMaxColors);
323 char buffer[kMaxColors * kBytesPerColormapEntry];
324 const unsigned char* src_colormap =
325 reinterpret_cast<const unsigned char*>(reader->GetConsecutiveData(
326 position_, colors_ * kBytesPerColormapEntry, buffer));
327 table_.resize(colors_);
328 for (Table::iterator iter = table_.begin(); iter != table_.end(); ++iter) {
329 *iter = SkPackARGB32NoCheck(255, src_colormap[0], src_colormap[1],
330 src_colormap[2]);
331 src_colormap += kBytesPerColormapEntry;
332 }
333 }
334
335 // Decodes this frame. |frameDecoded| will be set to true if the entire frame is
336 // decoded. Returns true if decoding progressed further than before without
337 // error, or there is insufficient new data to decode further. Otherwise, a
338 // decoding error occurred; returns false in this case.
339 bool GIFFrameContext::Decode(FastSharedBufferReader* reader,
340 GIFImageDecoder* client,
341 bool* frame_decoded) {
342 local_color_map_.BuildTable(reader);
343
344 *frame_decoded = false;
345 if (!lzw_context_) {
346 // Wait for more data to properly initialize GIFLZWContext.
347 if (!IsDataSizeDefined() || !IsHeaderDefined())
348 return true;
349
350 lzw_context_ = WTF::MakeUnique<GIFLZWContext>(client, this);
351 if (!lzw_context_->PrepareToDecode()) {
352 lzw_context_.reset();
353 return false;
354 }
355
356 current_lzw_block_ = 0;
357 }
358
359 // Some bad GIFs have extra blocks beyond the last row, which we don't want to
360 // decode.
361 while (current_lzw_block_ < lzw_blocks_.size() &&
362 lzw_context_->HasRemainingRows()) {
363 size_t block_position = lzw_blocks_[current_lzw_block_].block_position;
364 size_t block_size = lzw_blocks_[current_lzw_block_].block_size;
365 if (block_position + block_size > reader->size())
366 return false;
367
368 while (block_size) {
369 const char* segment = 0;
370 size_t segment_length = reader->GetSomeData(segment, block_position);
371 size_t decode_size = std::min(segment_length, block_size);
372 if (!lzw_context_->DoLZW(reinterpret_cast<const unsigned char*>(segment),
373 decode_size))
374 return false;
375 block_position += decode_size;
376 block_size -= decode_size;
377 }
378 ++current_lzw_block_;
379 }
380
381 // If this frame is data complete then the previous loop must have completely
382 // decoded all LZW blocks.
383 // There will be no more decoding for this frame so it's time to cleanup.
384 if (IsComplete()) {
385 *frame_decoded = true;
386 lzw_context_.reset();
387 }
388 return true;
389 }
390
391 // Decodes a frame using GIFFrameContext:decode(). Returns true if decoding has
392 // progressed, or false if an error has occurred.
393 bool GIFImageReader::Decode(size_t frame_index) {
394 FastSharedBufferReader reader(data_);
395 global_color_map_.BuildTable(&reader);
396
397 bool frame_decoded = false;
398 GIFFrameContext* current_frame = frames_[frame_index].get();
399
400 return current_frame->Decode(&reader, client_, &frame_decoded) &&
401 (!frame_decoded || client_->FrameComplete(frame_index));
402 }
403
404 bool GIFImageReader::Parse(GIFImageDecoder::GIFParseQuery query) {
405 if (bytes_read_ >= data_->size()) {
406 // This data has already been parsed. For example, in deferred
407 // decoding, a DecodingImageGenerator with more data may have already
408 // used this same ImageDecoder to decode. This can happen if two
409 // SkImages created by a DeferredImageDecoder are drawn/prerolled
410 // out of order (with respect to how much data they had at creation
411 // time).
412 return !client_->Failed();
413 }
414
415 return ParseData(bytes_read_, data_->size() - bytes_read_, query);
416 }
417
418 // Parse incoming GIF data stream into internal data structures.
419 // Return true if parsing has progressed or there is not enough data.
420 // Return false if a fatal error is encountered.
421 bool GIFImageReader::ParseData(size_t data_position,
422 size_t len,
423 GIFImageDecoder::GIFParseQuery query) {
424 if (!len) {
425 // No new data has come in since the last call, just ignore this call.
426 return true;
427 }
428
429 if (len < bytes_to_consume_)
430 return true;
431
432 FastSharedBufferReader reader(data_);
433
434 // A read buffer of 16 bytes is enough to accomodate all possible reads for
435 // parsing.
436 char read_buffer[16];
437
438 // Read as many components from |m_data| as possible. At the beginning of each
439 // iteration, |dataPosition| is advanced by m_bytesToConsume to point to the
440 // next component. |len| is decremented accordingly.
441 while (len >= bytes_to_consume_) {
442 const size_t current_component_position = data_position;
443
444 // Mark the current component as consumed. Note that currentComponent will
445 // remain pointed at this component until the next loop iteration.
446 data_position += bytes_to_consume_;
447 len -= bytes_to_consume_;
448
449 switch (state_) {
450 case GIFLZW:
451 DCHECK(!frames_.IsEmpty());
452 // m_bytesToConsume is the current component size because it hasn't been
453 // updated.
454 frames_.back()->AddLzwBlock(current_component_position,
455 bytes_to_consume_);
456 GETN(1, kGIFSubBlock);
457 break;
458
459 case kGIFLZWStart: {
460 DCHECK(!frames_.IsEmpty());
461 frames_.back()->SetDataSize(static_cast<unsigned char>(
462 reader.GetOneByte(current_component_position)));
463 GETN(1, kGIFSubBlock);
464 break;
465 }
466
467 case kGIFType: {
468 const char* current_component = reader.GetConsecutiveData(
469 current_component_position, 6, read_buffer);
470
471 // All GIF files begin with "GIF87a" or "GIF89a".
472 if (!memcmp(current_component, "GIF89a", 6))
473 version_ = 89;
474 else if (!memcmp(current_component, "GIF87a", 6))
475 version_ = 87;
476 else
477 return false;
478 GETN(7, kGIFGlobalHeader);
479 break;
480 }
481
482 case kGIFGlobalHeader: {
483 const unsigned char* current_component =
484 reinterpret_cast<const unsigned char*>(reader.GetConsecutiveData(
485 current_component_position, 5, read_buffer));
486
487 // This is the height and width of the "screen" or frame into which
488 // images are rendered. The individual images can be smaller than
489 // the screen size and located with an origin anywhere within the
490 // screen.
491 // Note that we don't inform the client of the size yet, as it might
492 // change after we read the first frame's image header.
493 screen_width_ = GETINT16(current_component);
494 screen_height_ = GETINT16(current_component + 2);
495
496 const size_t global_color_map_colors = 2
497 << (current_component[4] & 0x07);
498
499 if ((current_component[4] & 0x80) &&
500 global_color_map_colors > 0) { /* global map */
501 global_color_map_.SetTablePositionAndSize(data_position,
502 global_color_map_colors);
503 GETN(kBytesPerColormapEntry * global_color_map_colors,
504 kGIFGlobalColormap);
505 break;
506 }
507
508 GETN(1, kGIFImageStart);
509 break;
510 }
511
512 case kGIFGlobalColormap: {
513 global_color_map_.SetDefined();
514 GETN(1, kGIFImageStart);
515 break;
516 }
517
518 case kGIFImageStart: {
519 const char current_component =
520 reader.GetOneByte(current_component_position);
521
522 if (current_component == '!') { // extension.
523 GETN(2, kGIFExtension);
524 break;
525 }
526
527 if (current_component == ',') { // image separator.
528 GETN(9, kGIFImageHeader);
529 break;
530 }
531
532 // If we get anything other than ',' (image separator), '!'
533 // (extension), or ';' (trailer), there is extraneous data
534 // between blocks. The GIF87a spec tells us to keep reading
535 // until we find an image separator, but GIF89a says such
536 // a file is corrupt. We follow Mozilla's implementation and
537 // proceed as if the file were correctly terminated, so the
538 // GIF will display.
539 GETN(0, kGIFDone);
540 break;
541 }
542
543 case kGIFExtension: {
544 const unsigned char* current_component =
545 reinterpret_cast<const unsigned char*>(reader.GetConsecutiveData(
546 current_component_position, 2, read_buffer));
547
548 size_t bytes_in_block = current_component[1];
549 GIFState exception_state = kGIFSkipBlock;
550
551 switch (*current_component) {
552 case 0xf9:
553 exception_state = kGIFControlExtension;
554 // The GIF spec mandates that the GIFControlExtension header block
555 // length is 4 bytes, and the parser for this block reads 4 bytes,
556 // so we must enforce that the buffer contains at least this many
557 // bytes. If the GIF specifies a different length, we allow that, so
558 // long as it's larger; the additional data will simply be ignored.
559 bytes_in_block = std::max(bytes_in_block, static_cast<size_t>(4));
560 break;
561
562 // The GIF spec also specifies the lengths of the following two
563 // extensions' headers (as 12 and 11 bytes, respectively). Because we
564 // ignore the plain text extension entirely and sanity-check the
565 // actual length of the application extension header before reading
566 // it, we allow GIFs to deviate from these values in either direction.
567 // This is important for real-world compatibility, as GIFs in the wild
568 // exist with application extension headers that are both shorter and
569 // longer than 11 bytes.
570 case 0x01:
571 // ignoring plain text extension
572 break;
573
574 case 0xff:
575 exception_state = kGIFApplicationExtension;
576 break;
577
578 case 0xfe:
579 exception_state = kGIFConsumeComment;
580 break;
581 }
582
583 if (bytes_in_block)
584 GETN(bytes_in_block, exception_state);
585 else
586 GETN(1, kGIFImageStart);
587 break;
588 }
589
590 case kGIFConsumeBlock: {
591 const unsigned char current_component = static_cast<unsigned char>(
592 reader.GetOneByte(current_component_position));
593 if (!current_component)
594 GETN(1, kGIFImageStart);
595 else
596 GETN(current_component, kGIFSkipBlock);
597 break;
598 }
599
600 case kGIFSkipBlock: {
601 GETN(1, kGIFConsumeBlock);
602 break;
603 }
604
605 case kGIFControlExtension: {
606 const unsigned char* current_component =
607 reinterpret_cast<const unsigned char*>(reader.GetConsecutiveData(
608 current_component_position, 4, read_buffer));
609
610 AddFrameIfNecessary();
611 GIFFrameContext* current_frame = frames_.back().get();
612 if (*current_component & 0x1)
613 current_frame->SetTransparentPixel(current_component[3]);
614
615 // We ignore the "user input" bit.
616
617 // NOTE: This relies on the values in the FrameDisposalMethod enum
618 // matching those in the GIF spec!
619 int disposal_method = ((*current_component) >> 2) & 0x7;
620 if (disposal_method < 4) {
621 current_frame->SetDisposalMethod(
622 static_cast<ImageFrame::DisposalMethod>(disposal_method));
623 } else if (disposal_method == 4) {
624 // Some specs say that disposal method 3 is "overwrite previous",
625 // others that setting the third bit of the field (i.e. method 4) is.
626 // We map both to the same value.
627 current_frame->SetDisposalMethod(
628 ImageFrame::kDisposeOverwritePrevious);
629 }
630 current_frame->SetDelayTime(GETINT16(current_component + 1) * 10);
631 GETN(1, kGIFConsumeBlock);
632 break;
633 }
634
635 case kGIFCommentExtension: {
636 const unsigned char current_component = static_cast<unsigned char>(
637 reader.GetOneByte(current_component_position));
638 if (current_component)
639 GETN(current_component, kGIFConsumeComment);
640 else
641 GETN(1, kGIFImageStart);
642 break;
643 }
644
645 case kGIFConsumeComment: {
646 GETN(1, kGIFCommentExtension);
647 break;
648 }
649
650 case kGIFApplicationExtension: {
651 // Check for netscape application extension.
652 if (bytes_to_consume_ == 11) {
653 const unsigned char* current_component =
654 reinterpret_cast<const unsigned char*>(reader.GetConsecutiveData(
655 current_component_position, 11, read_buffer));
656
657 if (!memcmp(current_component, "NETSCAPE2.0", 11) ||
658 !memcmp(current_component, "ANIMEXTS1.0", 11))
659 GETN(1, kGIFNetscapeExtensionBlock);
660 }
661
662 if (state_ != kGIFNetscapeExtensionBlock)
663 GETN(1, kGIFConsumeBlock);
664 break;
665 }
666
667 // Netscape-specific GIF extension: animation looping.
668 case kGIFNetscapeExtensionBlock: {
669 const int current_component = static_cast<unsigned char>(
670 reader.GetOneByte(current_component_position));
671 // GIFConsumeNetscapeExtension always reads 3 bytes from the stream; we
672 // should at least wait for this amount.
673 if (current_component)
674 GETN(std::max(3, current_component), kGIFConsumeNetscapeExtension);
675 else
676 GETN(1, kGIFImageStart);
677 break;
678 }
679
680 // Parse netscape-specific application extensions
681 case kGIFConsumeNetscapeExtension: {
682 const unsigned char* current_component =
683 reinterpret_cast<const unsigned char*>(reader.GetConsecutiveData(
684 current_component_position, 3, read_buffer));
685
686 int netscape_extension = current_component[0] & 7;
687
688 // Loop entire animation specified # of times. Only read the loop count
689 // during the first iteration.
690 if (netscape_extension == 1) {
691 loop_count_ = GETINT16(current_component + 1);
692
693 // Zero loop count is infinite animation loop request.
694 if (!loop_count_)
695 loop_count_ = kAnimationLoopInfinite;
696
697 GETN(1, kGIFNetscapeExtensionBlock);
698 } else if (netscape_extension == 2) {
699 // Wait for specified # of bytes to enter buffer.
700
701 // Don't do this, this extension doesn't exist (isn't used at all)
702 // and doesn't do anything, as our streaming/buffering takes care of
703 // it all. See http://semmix.pl/color/exgraf/eeg24.htm .
704 GETN(1, kGIFNetscapeExtensionBlock);
705 } else {
706 // 0,3-7 are yet to be defined netscape extension codes
707 return false;
708 }
709 break;
710 }
711
712 case kGIFImageHeader: {
713 unsigned height, width, x_offset, y_offset;
714 const unsigned char* current_component =
715 reinterpret_cast<const unsigned char*>(reader.GetConsecutiveData(
716 current_component_position, 9, read_buffer));
717
718 /* Get image offsets, with respect to the screen origin */
719 x_offset = GETINT16(current_component);
720 y_offset = GETINT16(current_component + 2);
721
722 /* Get image width and height. */
723 width = GETINT16(current_component + 4);
724 height = GETINT16(current_component + 6);
725
726 // Some GIF files have frames that don't fit in the specified
727 // overall image size. For the first frame, we can simply enlarge
728 // the image size to allow the frame to be visible. We can't do
729 // this on subsequent frames because the rest of the decoding
730 // infrastructure assumes the image size won't change as we
731 // continue decoding, so any subsequent frames that are even
732 // larger will be cropped.
733 // Luckily, handling just the first frame is sufficient to deal
734 // with most cases, e.g. ones where the image size is erroneously
735 // set to zero, since usually the first frame completely fills
736 // the image.
737 if (CurrentFrameIsFirstFrame()) {
738 screen_height_ = std::max(screen_height_, y_offset + height);
739 screen_width_ = std::max(screen_width_, x_offset + width);
740 }
741
742 // Inform the client of the final size.
743 if (!sent_size_to_client_ && client_ &&
744 !client_->SetSize(screen_width_, screen_height_))
745 return false;
746 sent_size_to_client_ = true;
747
748 if (query == GIFImageDecoder::kGIFSizeQuery) {
749 // The decoder needs to stop. Hand back the number of bytes we
750 // consumed from the buffer minus 9 (the amount we consumed to read
751 // the header).
752 SetRemainingBytes(len + 9);
753 GETN(9, kGIFImageHeader);
754 return true;
755 }
756
757 AddFrameIfNecessary();
758 GIFFrameContext* current_frame = frames_.back().get();
759
760 current_frame->SetHeaderDefined();
761
762 // Work around more broken GIF files that have zero image width or
763 // height.
764 if (!height || !width) {
765 height = screen_height_;
766 width = screen_width_;
767 if (!height || !width)
768 return false;
769 }
770 current_frame->SetRect(x_offset, y_offset, width, height);
771 current_frame->SetInterlaced(current_component[8] & 0x40);
772
773 // Overlaying interlaced, transparent GIFs over
774 // existing image data using the Haeberli display hack
775 // requires saving the underlying image in order to
776 // avoid jaggies at the transparency edges. We are
777 // unprepared to deal with that, so don't display such
778 // images progressively. Which means only the first
779 // frame can be progressively displayed.
780 // FIXME: It is possible that a non-transparent frame
781 // can be interlaced and progressively displayed.
782 current_frame->SetProgressiveDisplay(CurrentFrameIsFirstFrame());
783
784 const bool is_local_colormap_defined = current_component[8] & 0x80;
785 if (is_local_colormap_defined) {
786 // The three low-order bits of currentComponent[8] specify the bits
787 // per pixel.
788 const size_t num_colors = 2 << (current_component[8] & 0x7);
789 current_frame->LocalColorMap().SetTablePositionAndSize(data_position,
790 num_colors);
791 GETN(kBytesPerColormapEntry * num_colors, kGIFImageColormap);
792 break;
793 }
794
795 GETN(1, kGIFLZWStart);
796 break;
797 }
798
799 case kGIFImageColormap: {
800 DCHECK(!frames_.IsEmpty());
801 frames_.back()->LocalColorMap().SetDefined();
802 GETN(1, kGIFLZWStart);
803 break;
804 }
805
806 case kGIFSubBlock: {
807 const size_t bytes_in_block = static_cast<unsigned char>(
808 reader.GetOneByte(current_component_position));
809 if (bytes_in_block)
810 GETN(bytes_in_block, GIFLZW);
811 else {
812 // Finished parsing one frame; Process next frame.
813 DCHECK(!frames_.IsEmpty());
814 // Note that some broken GIF files do not have enough LZW blocks to
815 // fully decode all rows; we treat this case as "frame complete".
816 frames_.back()->SetComplete();
817 GETN(1, kGIFImageStart);
818 }
819 break;
820 }
821
822 case kGIFDone: {
823 parse_completed_ = true;
824 return true;
825 }
826
827 default:
828 // We shouldn't ever get here.
829 return false;
830 break;
831 }
832 }
833
834 SetRemainingBytes(len);
835 return true;
836 }
837
838 void GIFImageReader::SetRemainingBytes(size_t remaining_bytes) {
839 DCHECK_LE(remaining_bytes, data_->size());
840 bytes_read_ = data_->size() - remaining_bytes;
841 }
842
843 void GIFImageReader::AddFrameIfNecessary() {
844 if (frames_.IsEmpty() || frames_.back()->IsComplete())
845 frames_.push_back(WTF::WrapUnique(new GIFFrameContext(frames_.size())));
846 }
847
848 // FIXME: Move this method to close to doLZW().
849 bool GIFLZWContext::PrepareToDecode() {
850 DCHECK(frame_context_->IsDataSizeDefined());
851 DCHECK(frame_context_->IsHeaderDefined());
852
853 // Since we use a codesize of 1 more than the datasize, we need to ensure
854 // that our datasize is strictly less than the kMaxDictionaryEntryBits.
855 if (frame_context_->DataSize() >= kMaxDictionaryEntryBits)
856 return false;
857 clear_code = 1 << frame_context_->DataSize();
858 avail = clear_code + 2;
859 oldcode = -1;
860 codesize = frame_context_->DataSize() + 1;
861 codemask = (1 << codesize) - 1;
862 datum = bits = 0;
863 ipass = frame_context_->Interlaced() ? 1 : 0;
864 irow = 0;
865
866 // We want to know the longest sequence encodable by a dictionary with
867 // kMaxDictionaryEntries entries. If we ignore the need to encode the base
868 // values themselves at the beginning of the dictionary, as well as the need
869 // for a clear code or a termination code, we could use every entry to
870 // encode a series of multiple values. If the input value stream looked
871 // like "AAAAA..." (a long string of just one value), the first dictionary
872 // entry would encode AA, the next AAA, the next AAAA, and so forth. Thus
873 // the longest sequence would be kMaxDictionaryEntries + 1 values.
874 //
875 // However, we have to account for reserved entries. The first |datasize|
876 // bits are reserved for the base values, and the next two entries are
877 // reserved for the clear code and termination code. In theory a GIF can
878 // set the datasize to 0, meaning we have just two reserved entries, making
879 // the longest sequence (kMaxDictionaryEntries + 1) - 2 values long. Since
880 // each value is a byte, this is also the number of bytes in the longest
881 // encodable sequence.
882 const size_t kMaxBytes = kMaxDictionaryEntries - 1;
883
884 // Now allocate the output buffer. We decode directly into this buffer
885 // until we have at least one row worth of data, then call outputRow().
886 // This means worst case we may have (row width - 1) bytes in the buffer
887 // and then decode a sequence |maxBytes| long to append.
888 row_buffer.resize(frame_context_->Width() - 1 + kMaxBytes);
889 row_iter = row_buffer.begin();
890 rows_remaining = frame_context_->Height();
891
892 // Clearing the whole suffix table lets us be more tolerant of bad data.
893 for (int i = 0; i < clear_code; ++i) {
894 suffix[i] = i;
895 suffix_length[i] = 1;
896 }
897 return true;
898 }
899
900 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/image-decoders/gif/GIFImageReader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698