Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 // The condition check is taken out of the loop to enhance performance. | 152 // The condition check is taken out of the loop to enhance performance. |
| 153 // This optimization reduces decoding time by about 15% for a 3MB image. | 153 // This optimization reduces decoding time by about 15% for a 3MB image. |
| 154 if (write_transparent_pixels) { | 154 if (write_transparent_pixels) { |
| 155 for (; row_begin != row_end; ++row_begin, ++current_address) { | 155 for (; row_begin != row_end; ++row_begin, ++current_address) { |
| 156 const size_t source_value = *row_begin; | 156 const size_t source_value = *row_begin; |
| 157 if ((source_value != transparent_pixel) && | 157 if ((source_value != transparent_pixel) && |
| 158 (source_value < color_table.size())) { | 158 (source_value < color_table.size())) { |
| 159 *current_address = color_table_iter[source_value]; | 159 *current_address = color_table_iter[source_value]; |
| 160 } else { | 160 } else { |
| 161 *current_address = 0; | 161 *current_address = 0; |
| 162 current_buffer_saw_alpha_ = true; | |
| 163 } | 162 } |
| 164 } | 163 } |
| 165 } else { | 164 } else { |
| 166 for (; row_begin != row_end; ++row_begin, ++current_address) { | 165 for (; row_begin != row_end; ++row_begin, ++current_address) { |
| 167 const size_t source_value = *row_begin; | 166 const size_t source_value = *row_begin; |
| 168 if ((source_value != transparent_pixel) && | 167 if ((source_value != transparent_pixel) && |
| 169 (source_value < color_table.size())) | 168 (source_value < color_table.size())) |
| 170 *current_address = color_table_iter[source_value]; | 169 *current_address = color_table_iter[source_value]; |
| 171 else | |
| 172 current_buffer_saw_alpha_ = true; | |
| 173 } | 170 } |
| 174 } | 171 } |
| 175 | 172 |
| 176 // Tell the frame to copy the row data if need be. | 173 // Tell the frame to copy the row data if need be. |
| 177 if (repeat_count > 1) | 174 if (repeat_count > 1) |
| 178 buffer.CopyRowNTimes(x_begin, x_end, y_begin, y_end); | 175 buffer.CopyRowNTimes(x_begin, x_end, y_begin, y_end); |
| 179 | 176 |
| 180 buffer.SetPixelsChanged(true); | 177 buffer.SetPixelsChanged(true); |
| 181 return true; | 178 return true; |
| 182 } | 179 } |
| 183 | 180 |
| 184 bool GIFImageDecoder::ParseCompleted() const { | 181 bool GIFImageDecoder::ParseCompleted() const { |
| 185 return reader_ && reader_->ParseCompleted(); | 182 return reader_ && reader_->ParseCompleted(); |
| 186 } | 183 } |
| 187 | 184 |
| 188 bool GIFImageDecoder::FrameComplete(size_t frame_index) { | 185 bool GIFImageDecoder::FrameComplete(size_t frame_index) { |
| 189 // Initialize the frame if necessary. Some GIFs insert do-nothing frames, | 186 // Initialize the frame if necessary. Some GIFs insert do-nothing frames, |
|
scroggo_chromium
2017/05/31 14:27:50
Should we consider the case of a do-nothing frame?
cblume
2017/05/31 20:35:05
I imagine there might be two types of do-nothing f
scroggo_chromium
2017/05/31 21:12:15
Notice the comment - a "do-nothing" frame means we
| |
| 190 // in which case we never reach HaveDecodedRow() before getting here. | 187 // in which case we never reach HaveDecodedRow() before getting here. |
| 191 if (!InitFrameBuffer(frame_index)) | 188 if (!InitFrameBuffer(frame_index)) |
| 192 return SetFailed(); | 189 return SetFailed(); |
| 193 | 190 |
| 194 if (!current_buffer_saw_alpha_) | 191 ImageFrame& buffer = frame_buffer_cache_[frame_index]; |
| 195 CorrectAlphaWhenFrameBufferSawNoAlpha(frame_index); | |
| 196 | 192 |
| 197 frame_buffer_cache_[frame_index].SetStatus(ImageFrame::kFrameComplete); | 193 const GIFFrameContext* frame_context = reader_->FrameContext(frame_index); |
| 194 const size_t transparent_pixel = frame_context->TransparentPixel(); | |
| 195 const GIFColorMap::Table& color_table = | |
| 196 frame_context->LocalColorMap().IsDefined() | |
| 197 ? frame_context->LocalColorMap().GetTable() | |
| 198 : reader_->GlobalColorMap().GetTable(); | |
| 199 buffer.SetHasAlpha(transparent_pixel <= color_table.size()); | |
| 200 | |
| 201 buffer.SetStatus(ImageFrame::kFrameComplete); | |
| 198 | 202 |
| 199 return true; | 203 return true; |
| 200 } | 204 } |
| 201 | 205 |
| 202 void GIFImageDecoder::ClearFrameBuffer(size_t frame_index) { | 206 void GIFImageDecoder::ClearFrameBuffer(size_t frame_index) { |
| 203 if (reader_ && frame_buffer_cache_[frame_index].GetStatus() == | 207 if (reader_ && frame_buffer_cache_[frame_index].GetStatus() == |
| 204 ImageFrame::kFramePartial) { | 208 ImageFrame::kFramePartial) { |
| 205 // Reset the state of the partial frame in the reader so that the frame | 209 // Reset the state of the partial frame in the reader so that the frame |
| 206 // can be decoded again when requested. | 210 // can be decoded again when requested. |
| 207 reader_->ClearDecodeState(frame_index); | 211 reader_->ClearDecodeState(frame_index); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 262 | 266 |
| 263 if (!reader_) { | 267 if (!reader_) { |
| 264 reader_ = WTF::MakeUnique<GIFImageReader>(this); | 268 reader_ = WTF::MakeUnique<GIFImageReader>(this); |
| 265 reader_->SetData(data_); | 269 reader_->SetData(data_); |
| 266 } | 270 } |
| 267 | 271 |
| 268 if (!reader_->Parse(query)) | 272 if (!reader_->Parse(query)) |
| 269 SetFailed(); | 273 SetFailed(); |
| 270 } | 274 } |
| 271 | 275 |
| 272 void GIFImageDecoder::OnInitFrameBuffer(size_t frame_index) { | |
| 273 current_buffer_saw_alpha_ = false; | |
| 274 } | |
| 275 | |
| 276 bool GIFImageDecoder::CanReusePreviousFrameBuffer(size_t frame_index) const { | 276 bool GIFImageDecoder::CanReusePreviousFrameBuffer(size_t frame_index) const { |
| 277 DCHECK(frame_index < frame_buffer_cache_.size()); | 277 DCHECK(frame_index < frame_buffer_cache_.size()); |
| 278 return frame_buffer_cache_[frame_index].GetDisposalMethod() != | 278 return frame_buffer_cache_[frame_index].GetDisposalMethod() != |
| 279 ImageFrame::kDisposeOverwritePrevious; | 279 ImageFrame::kDisposeOverwritePrevious; |
| 280 } | 280 } |
| 281 | 281 |
| 282 } // namespace blink | 282 } // namespace blink |
| OLD | NEW |