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

Side by Side Diff: third_party/libwebp/dec/idec.c

Issue 421003002: libwebp: update to 0.4.1 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 0.4.1-final Created 6 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/libwebp/dec/frame.c ('k') | third_party/libwebp/dec/io.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 Google Inc. All Rights Reserved. 1 // Copyright 2011 Google Inc. All Rights Reserved.
2 // 2 //
3 // Use of this source code is governed by a BSD-style license 3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the COPYING file in the root of the source 4 // that can be found in the COPYING file in the root of the source
5 // tree. An additional intellectual property rights grant can be found 5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may 6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree. 7 // be found in the AUTHORS file in the root of the source tree.
8 // ----------------------------------------------------------------------------- 8 // -----------------------------------------------------------------------------
9 // 9 //
10 // Incremental decoding 10 // Incremental decoding
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 struct WebPIDecoder { 65 struct WebPIDecoder {
66 DecState state_; // current decoding state 66 DecState state_; // current decoding state
67 WebPDecParams params_; // Params to store output info 67 WebPDecParams params_; // Params to store output info
68 int is_lossless_; // for down-casting 'dec_'. 68 int is_lossless_; // for down-casting 'dec_'.
69 void* dec_; // either a VP8Decoder or a VP8LDecoder instance 69 void* dec_; // either a VP8Decoder or a VP8LDecoder instance
70 VP8Io io_; 70 VP8Io io_;
71 71
72 MemBuffer mem_; // input memory buffer. 72 MemBuffer mem_; // input memory buffer.
73 WebPDecBuffer output_; // output buffer (when no external one is supplied) 73 WebPDecBuffer output_; // output buffer (when no external one is supplied)
74 size_t chunk_size_; // Compressed VP8/VP8L size extracted from Header. 74 size_t chunk_size_; // Compressed VP8/VP8L size extracted from Header.
75
76 int last_mb_y_; // last row reached for intra-mode decoding
75 }; 77 };
76 78
77 // MB context to restore in case VP8DecodeMB() fails 79 // MB context to restore in case VP8DecodeMB() fails
78 typedef struct { 80 typedef struct {
79 VP8MB left_; 81 VP8MB left_;
80 VP8MB info_; 82 VP8MB info_;
81 uint8_t intra_t_[4];
82 uint8_t intra_l_[4];
83 VP8BitReader br_;
84 VP8BitReader token_br_; 83 VP8BitReader token_br_;
85 } MBContext; 84 } MBContext;
86 85
87 //------------------------------------------------------------------------------ 86 //------------------------------------------------------------------------------
88 // MemBuffer: incoming data handling 87 // MemBuffer: incoming data handling
89 88
90 static void RemapBitReader(VP8BitReader* const br, ptrdiff_t offset) {
91 if (br->buf_ != NULL) {
92 br->buf_ += offset;
93 br->buf_end_ += offset;
94 }
95 }
96
97 static WEBP_INLINE size_t MemDataSize(const MemBuffer* mem) { 89 static WEBP_INLINE size_t MemDataSize(const MemBuffer* mem) {
98 return (mem->end_ - mem->start_); 90 return (mem->end_ - mem->start_);
99 } 91 }
100 92
101 // Check if we need to preserve the compressed alpha data, as it may not have 93 // Check if we need to preserve the compressed alpha data, as it may not have
102 // been decoded yet. 94 // been decoded yet.
103 static int NeedCompressedAlpha(const WebPIDecoder* const idec) { 95 static int NeedCompressedAlpha(const WebPIDecoder* const idec) {
104 if (idec->state_ == STATE_WEBP_HEADER) { 96 if (idec->state_ == STATE_WEBP_HEADER) {
105 // We haven't parsed the headers yet, so we don't know whether the image is 97 // We haven't parsed the headers yet, so we don't know whether the image is
106 // lossy or lossless. This also means that we haven't parsed the ALPH chunk. 98 // lossy or lossless. This also means that we haven't parsed the ALPH chunk.
(...skipping 16 matching lines...) Expand all
123 idec->io_.data = new_base; 115 idec->io_.data = new_base;
124 idec->io_.data_size = MemDataSize(mem); 116 idec->io_.data_size = MemDataSize(mem);
125 117
126 if (idec->dec_ != NULL) { 118 if (idec->dec_ != NULL) {
127 if (!idec->is_lossless_) { 119 if (!idec->is_lossless_) {
128 VP8Decoder* const dec = (VP8Decoder*)idec->dec_; 120 VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
129 const int last_part = dec->num_parts_ - 1; 121 const int last_part = dec->num_parts_ - 1;
130 if (offset != 0) { 122 if (offset != 0) {
131 int p; 123 int p;
132 for (p = 0; p <= last_part; ++p) { 124 for (p = 0; p <= last_part; ++p) {
133 RemapBitReader(dec->parts_ + p, offset); 125 VP8RemapBitReader(dec->parts_ + p, offset);
134 } 126 }
135 // Remap partition #0 data pointer to new offset, but only in MAP 127 // Remap partition #0 data pointer to new offset, but only in MAP
136 // mode (in APPEND mode, partition #0 is copied into a fixed memory). 128 // mode (in APPEND mode, partition #0 is copied into a fixed memory).
137 if (mem->mode_ == MEM_MODE_MAP) { 129 if (mem->mode_ == MEM_MODE_MAP) {
138 RemapBitReader(&dec->br_, offset); 130 VP8RemapBitReader(&dec->br_, offset);
139 } 131 }
140 } 132 }
141 assert(last_part >= 0); 133 assert(last_part >= 0);
142 dec->parts_[last_part].buf_end_ = mem->buf_ + mem->end_; 134 dec->parts_[last_part].buf_end_ = mem->buf_ + mem->end_;
143 if (NeedCompressedAlpha(idec)) { 135 if (NeedCompressedAlpha(idec)) {
144 ALPHDecoder* const alph_dec = dec->alph_dec_; 136 ALPHDecoder* const alph_dec = dec->alph_dec_;
145 dec->alpha_data_ += offset; 137 dec->alpha_data_ += offset;
146 if (alph_dec != NULL) { 138 if (alph_dec != NULL) {
147 if (alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION) { 139 if (alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION) {
148 VP8LDecoder* const alph_vp8l_dec = alph_dec->vp8l_dec_; 140 VP8LDecoder* const alph_vp8l_dec = alph_dec->vp8l_dec_;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 174
183 if (mem->end_ + data_size > mem->buf_size_) { // Need some free memory 175 if (mem->end_ + data_size > mem->buf_size_) { // Need some free memory
184 const size_t new_mem_start = old_start - old_base; 176 const size_t new_mem_start = old_start - old_base;
185 const size_t current_size = MemDataSize(mem) + new_mem_start; 177 const size_t current_size = MemDataSize(mem) + new_mem_start;
186 const uint64_t new_size = (uint64_t)current_size + data_size; 178 const uint64_t new_size = (uint64_t)current_size + data_size;
187 const uint64_t extra_size = (new_size + CHUNK_SIZE - 1) & ~(CHUNK_SIZE - 1); 179 const uint64_t extra_size = (new_size + CHUNK_SIZE - 1) & ~(CHUNK_SIZE - 1);
188 uint8_t* const new_buf = 180 uint8_t* const new_buf =
189 (uint8_t*)WebPSafeMalloc(extra_size, sizeof(*new_buf)); 181 (uint8_t*)WebPSafeMalloc(extra_size, sizeof(*new_buf));
190 if (new_buf == NULL) return 0; 182 if (new_buf == NULL) return 0;
191 memcpy(new_buf, old_base, current_size); 183 memcpy(new_buf, old_base, current_size);
192 free(mem->buf_); 184 WebPSafeFree(mem->buf_);
193 mem->buf_ = new_buf; 185 mem->buf_ = new_buf;
194 mem->buf_size_ = (size_t)extra_size; 186 mem->buf_size_ = (size_t)extra_size;
195 mem->start_ = new_mem_start; 187 mem->start_ = new_mem_start;
196 mem->end_ = current_size; 188 mem->end_ = current_size;
197 } 189 }
198 190
199 memcpy(mem->buf_ + mem->end_, data, data_size); 191 memcpy(mem->buf_ + mem->end_, data, data_size);
200 mem->end_ += data_size; 192 mem->end_ += data_size;
201 assert(mem->end_ <= mem->buf_size_); 193 assert(mem->end_ <= mem->buf_size_);
202 194
(...skipping 21 matching lines...) Expand all
224 mem->mode_ = MEM_MODE_NONE; 216 mem->mode_ = MEM_MODE_NONE;
225 mem->buf_ = NULL; 217 mem->buf_ = NULL;
226 mem->buf_size_ = 0; 218 mem->buf_size_ = 0;
227 mem->part0_buf_ = NULL; 219 mem->part0_buf_ = NULL;
228 mem->part0_size_ = 0; 220 mem->part0_size_ = 0;
229 } 221 }
230 222
231 static void ClearMemBuffer(MemBuffer* const mem) { 223 static void ClearMemBuffer(MemBuffer* const mem) {
232 assert(mem); 224 assert(mem);
233 if (mem->mode_ == MEM_MODE_APPEND) { 225 if (mem->mode_ == MEM_MODE_APPEND) {
234 free(mem->buf_); 226 WebPSafeFree(mem->buf_);
235 free((void*)mem->part0_buf_); 227 WebPSafeFree((void*)mem->part0_buf_);
236 } 228 }
237 } 229 }
238 230
239 static int CheckMemBufferMode(MemBuffer* const mem, MemBufferMode expected) { 231 static int CheckMemBufferMode(MemBuffer* const mem, MemBufferMode expected) {
240 if (mem->mode_ == MEM_MODE_NONE) { 232 if (mem->mode_ == MEM_MODE_NONE) {
241 mem->mode_ = expected; // switch to the expected mode 233 mem->mode_ = expected; // switch to the expected mode
242 } else if (mem->mode_ != expected) { 234 } else if (mem->mode_ != expected) {
243 return 0; // we mixed the modes => error 235 return 0; // we mixed the modes => error
244 } 236 }
245 assert(mem->mode_ == expected); // mode is ok 237 assert(mem->mode_ == expected); // mode is ok
246 return 1; 238 return 1;
247 } 239 }
248 240
241 // To be called last.
242 static VP8StatusCode FinishDecoding(WebPIDecoder* const idec) {
243 #if WEBP_DECODER_ABI_VERSION > 0x0203
244 const WebPDecoderOptions* const options = idec->params_.options;
245 WebPDecBuffer* const output = idec->params_.output;
246
247 idec->state_ = STATE_DONE;
248 if (options != NULL && options->flip) {
249 return WebPFlipBuffer(output);
250 }
251 #endif
252 idec->state_ = STATE_DONE;
253 return VP8_STATUS_OK;
254 }
255
249 //------------------------------------------------------------------------------ 256 //------------------------------------------------------------------------------
250 // Macroblock-decoding contexts 257 // Macroblock-decoding contexts
251 258
252 static void SaveContext(const VP8Decoder* dec, const VP8BitReader* token_br, 259 static void SaveContext(const VP8Decoder* dec, const VP8BitReader* token_br,
253 MBContext* const context) { 260 MBContext* const context) {
254 const VP8BitReader* const br = &dec->br_; 261 context->left_ = dec->mb_info_[-1];
255 const VP8MB* const left = dec->mb_info_ - 1; 262 context->info_ = dec->mb_info_[dec->mb_x_];
256 const VP8MB* const info = dec->mb_info_ + dec->mb_x_;
257
258 context->left_ = *left;
259 context->info_ = *info;
260 context->br_ = *br;
261 context->token_br_ = *token_br; 263 context->token_br_ = *token_br;
262 memcpy(context->intra_t_, dec->intra_t_ + 4 * dec->mb_x_, 4);
263 memcpy(context->intra_l_, dec->intra_l_, 4);
264 } 264 }
265 265
266 static void RestoreContext(const MBContext* context, VP8Decoder* const dec, 266 static void RestoreContext(const MBContext* context, VP8Decoder* const dec,
267 VP8BitReader* const token_br) { 267 VP8BitReader* const token_br) {
268 VP8BitReader* const br = &dec->br_; 268 dec->mb_info_[-1] = context->left_;
269 VP8MB* const left = dec->mb_info_ - 1; 269 dec->mb_info_[dec->mb_x_] = context->info_;
270 VP8MB* const info = dec->mb_info_ + dec->mb_x_;
271
272 *left = context->left_;
273 *info = context->info_;
274 *br = context->br_;
275 *token_br = context->token_br_; 270 *token_br = context->token_br_;
276 memcpy(dec->intra_t_ + 4 * dec->mb_x_, context->intra_t_, 4);
277 memcpy(dec->intra_l_, context->intra_l_, 4);
278 } 271 }
279 272
280 //------------------------------------------------------------------------------ 273 //------------------------------------------------------------------------------
281 274
282 static VP8StatusCode IDecError(WebPIDecoder* const idec, VP8StatusCode error) { 275 static VP8StatusCode IDecError(WebPIDecoder* const idec, VP8StatusCode error) {
283 if (idec->state_ == STATE_VP8_DATA) { 276 if (idec->state_ == STATE_VP8_DATA) {
284 VP8Io* const io = &idec->io_; 277 VP8Io* const io = &idec->io_;
285 if (io->teardown != NULL) { 278 if (io->teardown != NULL) {
286 io->teardown(io); 279 io->teardown(io);
287 } 280 }
(...skipping 15 matching lines...) Expand all
303 // Headers 296 // Headers
304 static VP8StatusCode DecodeWebPHeaders(WebPIDecoder* const idec) { 297 static VP8StatusCode DecodeWebPHeaders(WebPIDecoder* const idec) {
305 MemBuffer* const mem = &idec->mem_; 298 MemBuffer* const mem = &idec->mem_;
306 const uint8_t* data = mem->buf_ + mem->start_; 299 const uint8_t* data = mem->buf_ + mem->start_;
307 size_t curr_size = MemDataSize(mem); 300 size_t curr_size = MemDataSize(mem);
308 VP8StatusCode status; 301 VP8StatusCode status;
309 WebPHeaderStructure headers; 302 WebPHeaderStructure headers;
310 303
311 headers.data = data; 304 headers.data = data;
312 headers.data_size = curr_size; 305 headers.data_size = curr_size;
306 headers.have_all_data = 0;
313 status = WebPParseHeaders(&headers); 307 status = WebPParseHeaders(&headers);
314 if (status == VP8_STATUS_NOT_ENOUGH_DATA) { 308 if (status == VP8_STATUS_NOT_ENOUGH_DATA) {
315 return VP8_STATUS_SUSPENDED; // We haven't found a VP8 chunk yet. 309 return VP8_STATUS_SUSPENDED; // We haven't found a VP8 chunk yet.
316 } else if (status != VP8_STATUS_OK) { 310 } else if (status != VP8_STATUS_OK) {
317 return IDecError(idec, status); 311 return IDecError(idec, status);
318 } 312 }
319 313
320 idec->chunk_size_ = headers.compressed_size; 314 idec->chunk_size_ = headers.compressed_size;
321 idec->is_lossless_ = headers.is_lossless; 315 idec->is_lossless_ = headers.is_lossless;
322 if (!idec->is_lossless_) { 316 if (!idec->is_lossless_) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 VP8Decoder* const dec = (VP8Decoder*)idec->dec_; 361 VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
368 VP8BitReader* const br = &dec->br_; 362 VP8BitReader* const br = &dec->br_;
369 const size_t psize = br->buf_end_ - br->buf_; 363 const size_t psize = br->buf_end_ - br->buf_;
370 MemBuffer* const mem = &idec->mem_; 364 MemBuffer* const mem = &idec->mem_;
371 assert(!idec->is_lossless_); 365 assert(!idec->is_lossless_);
372 assert(mem->part0_buf_ == NULL); 366 assert(mem->part0_buf_ == NULL);
373 assert(psize > 0); 367 assert(psize > 0);
374 assert(psize <= mem->part0_size_); // Format limit: no need for runtime check 368 assert(psize <= mem->part0_size_); // Format limit: no need for runtime check
375 if (mem->mode_ == MEM_MODE_APPEND) { 369 if (mem->mode_ == MEM_MODE_APPEND) {
376 // We copy and grab ownership of the partition #0 data. 370 // We copy and grab ownership of the partition #0 data.
377 uint8_t* const part0_buf = (uint8_t*)malloc(psize); 371 uint8_t* const part0_buf = (uint8_t*)WebPSafeMalloc(1ULL, psize);
378 if (part0_buf == NULL) { 372 if (part0_buf == NULL) {
379 return 0; 373 return 0;
380 } 374 }
381 memcpy(part0_buf, br->buf_, psize); 375 memcpy(part0_buf, br->buf_, psize);
382 mem->part0_buf_ = part0_buf; 376 mem->part0_buf_ = part0_buf;
383 br->buf_ = part0_buf; 377 br->buf_ = part0_buf;
384 br->buf_end_ = part0_buf + psize; 378 br->buf_end_ = part0_buf + psize;
385 } else { 379 } else {
386 // Else: just keep pointers to the partition #0's data in dec_->br_. 380 // Else: just keep pointers to the partition #0's data in dec_->br_.
387 } 381 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 return VP8_STATUS_OK; 433 return VP8_STATUS_OK;
440 } 434 }
441 435
442 // Remaining partitions 436 // Remaining partitions
443 static VP8StatusCode DecodeRemaining(WebPIDecoder* const idec) { 437 static VP8StatusCode DecodeRemaining(WebPIDecoder* const idec) {
444 VP8Decoder* const dec = (VP8Decoder*)idec->dec_; 438 VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
445 VP8Io* const io = &idec->io_; 439 VP8Io* const io = &idec->io_;
446 440
447 assert(dec->ready_); 441 assert(dec->ready_);
448 for (; dec->mb_y_ < dec->mb_h_; ++dec->mb_y_) { 442 for (; dec->mb_y_ < dec->mb_h_; ++dec->mb_y_) {
449 VP8BitReader* token_br = &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)]; 443 if (idec->last_mb_y_ != dec->mb_y_) {
444 if (!VP8ParseIntraModeRow(&dec->br_, dec)) {
445 // note: normally, error shouldn't occur since we already have the whole
446 // partition0 available here in DecodeRemaining(). Reaching EOF while
447 // reading intra modes really means a BITSTREAM_ERROR.
448 return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
449 }
450 idec->last_mb_y_ = dec->mb_y_;
451 }
450 for (; dec->mb_x_ < dec->mb_w_; ++dec->mb_x_) { 452 for (; dec->mb_x_ < dec->mb_w_; ++dec->mb_x_) {
453 VP8BitReader* const token_br =
454 &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)];
451 MBContext context; 455 MBContext context;
452 SaveContext(dec, token_br, &context); 456 SaveContext(dec, token_br, &context);
453 if (!VP8DecodeMB(dec, token_br)) { 457 if (!VP8DecodeMB(dec, token_br)) {
454 RestoreContext(&context, dec, token_br);
455 // We shouldn't fail when MAX_MB data was available 458 // We shouldn't fail when MAX_MB data was available
456 if (dec->num_parts_ == 1 && MemDataSize(&idec->mem_) > MAX_MB_SIZE) { 459 if (dec->num_parts_ == 1 && MemDataSize(&idec->mem_) > MAX_MB_SIZE) {
457 return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR); 460 return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
458 } 461 }
462 RestoreContext(&context, dec, token_br);
459 return VP8_STATUS_SUSPENDED; 463 return VP8_STATUS_SUSPENDED;
460 } 464 }
461 // Release buffer only if there is only one partition 465 // Release buffer only if there is only one partition
462 if (dec->num_parts_ == 1) { 466 if (dec->num_parts_ == 1) {
463 idec->mem_.start_ = token_br->buf_ - idec->mem_.buf_; 467 idec->mem_.start_ = token_br->buf_ - idec->mem_.buf_;
464 assert(idec->mem_.start_ <= idec->mem_.end_); 468 assert(idec->mem_.start_ <= idec->mem_.end_);
465 } 469 }
466 } 470 }
467 VP8InitScanline(dec); // Prepare for next scanline 471 VP8InitScanline(dec); // Prepare for next scanline
468 472
469 // Reconstruct, filter and emit the row. 473 // Reconstruct, filter and emit the row.
470 if (!VP8ProcessRow(dec, io)) { 474 if (!VP8ProcessRow(dec, io)) {
471 return IDecError(idec, VP8_STATUS_USER_ABORT); 475 return IDecError(idec, VP8_STATUS_USER_ABORT);
472 } 476 }
473 } 477 }
474 // Synchronize the thread and check for errors. 478 // Synchronize the thread and check for errors.
475 if (!VP8ExitCritical(dec, io)) { 479 if (!VP8ExitCritical(dec, io)) {
476 return IDecError(idec, VP8_STATUS_USER_ABORT); 480 return IDecError(idec, VP8_STATUS_USER_ABORT);
477 } 481 }
478 dec->ready_ = 0; 482 dec->ready_ = 0;
479 idec->state_ = STATE_DONE; 483 return FinishDecoding(idec);
480
481 return VP8_STATUS_OK;
482 } 484 }
483 485
484 static VP8StatusCode ErrorStatusLossless(WebPIDecoder* const idec, 486 static VP8StatusCode ErrorStatusLossless(WebPIDecoder* const idec,
485 VP8StatusCode status) { 487 VP8StatusCode status) {
486 if (status == VP8_STATUS_SUSPENDED || status == VP8_STATUS_NOT_ENOUGH_DATA) { 488 if (status == VP8_STATUS_SUSPENDED || status == VP8_STATUS_NOT_ENOUGH_DATA) {
487 return VP8_STATUS_SUSPENDED; 489 return VP8_STATUS_SUSPENDED;
488 } 490 }
489 return IDecError(idec, status); 491 return IDecError(idec, status);
490 } 492 }
491 493
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 // At present Lossless decoder can't decode image incrementally. So wait till 525 // At present Lossless decoder can't decode image incrementally. So wait till
524 // all the image data is aggregated before image can be decoded. 526 // all the image data is aggregated before image can be decoded.
525 if (curr_size < idec->chunk_size_) { 527 if (curr_size < idec->chunk_size_) {
526 return VP8_STATUS_SUSPENDED; 528 return VP8_STATUS_SUSPENDED;
527 } 529 }
528 530
529 if (!VP8LDecodeImage(dec)) { 531 if (!VP8LDecodeImage(dec)) {
530 return ErrorStatusLossless(idec, dec->status_); 532 return ErrorStatusLossless(idec, dec->status_);
531 } 533 }
532 534
533 idec->state_ = STATE_DONE; 535 return FinishDecoding(idec);
534
535 return VP8_STATUS_OK;
536 } 536 }
537 537
538 // Main decoding loop 538 // Main decoding loop
539 static VP8StatusCode IDecode(WebPIDecoder* idec) { 539 static VP8StatusCode IDecode(WebPIDecoder* idec) {
540 VP8StatusCode status = VP8_STATUS_SUSPENDED; 540 VP8StatusCode status = VP8_STATUS_SUSPENDED;
541 541
542 if (idec->state_ == STATE_WEBP_HEADER) { 542 if (idec->state_ == STATE_WEBP_HEADER) {
543 status = DecodeWebPHeaders(idec); 543 status = DecodeWebPHeaders(idec);
544 } else { 544 } else {
545 if (idec->dec_ == NULL) { 545 if (idec->dec_ == NULL) {
(...skipping 15 matching lines...) Expand all
561 if (idec->state_ == STATE_VP8L_DATA) { 561 if (idec->state_ == STATE_VP8L_DATA) {
562 status = DecodeVP8LData(idec); 562 status = DecodeVP8LData(idec);
563 } 563 }
564 return status; 564 return status;
565 } 565 }
566 566
567 //------------------------------------------------------------------------------ 567 //------------------------------------------------------------------------------
568 // Public functions 568 // Public functions
569 569
570 WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer) { 570 WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer) {
571 WebPIDecoder* idec = (WebPIDecoder*)calloc(1, sizeof(*idec)); 571 WebPIDecoder* idec = (WebPIDecoder*)WebPSafeCalloc(1ULL, sizeof(*idec));
572 if (idec == NULL) { 572 if (idec == NULL) {
573 return NULL; 573 return NULL;
574 } 574 }
575 575
576 idec->state_ = STATE_WEBP_HEADER; 576 idec->state_ = STATE_WEBP_HEADER;
577 idec->chunk_size_ = 0; 577 idec->chunk_size_ = 0;
578 578
579 idec->last_mb_y_ = -1;
580
579 InitMemBuffer(&idec->mem_); 581 InitMemBuffer(&idec->mem_);
580 WebPInitDecBuffer(&idec->output_); 582 WebPInitDecBuffer(&idec->output_);
581 VP8InitIo(&idec->io_); 583 VP8InitIo(&idec->io_);
582 584
583 WebPResetDecParams(&idec->params_); 585 WebPResetDecParams(&idec->params_);
584 idec->params_.output = (output_buffer != NULL) ? output_buffer 586 idec->params_.output = (output_buffer != NULL) ? output_buffer
585 : &idec->output_; 587 : &idec->output_;
586 WebPInitCustomIo(&idec->params_, &idec->io_); // Plug the I/O functions. 588 WebPInitCustomIo(&idec->params_, &idec->io_); // Plug the I/O functions.
587 589
588 return idec; 590 return idec;
(...skipping 29 matching lines...) Expand all
618 // Synchronize the thread, clean-up and check for errors. 620 // Synchronize the thread, clean-up and check for errors.
619 VP8ExitCritical((VP8Decoder*)idec->dec_, &idec->io_); 621 VP8ExitCritical((VP8Decoder*)idec->dec_, &idec->io_);
620 } 622 }
621 VP8Delete((VP8Decoder*)idec->dec_); 623 VP8Delete((VP8Decoder*)idec->dec_);
622 } else { 624 } else {
623 VP8LDelete((VP8LDecoder*)idec->dec_); 625 VP8LDelete((VP8LDecoder*)idec->dec_);
624 } 626 }
625 } 627 }
626 ClearMemBuffer(&idec->mem_); 628 ClearMemBuffer(&idec->mem_);
627 WebPFreeDecBuffer(&idec->output_); 629 WebPFreeDecBuffer(&idec->output_);
628 free(idec); 630 WebPSafeFree(idec);
629 } 631 }
630 632
631 //------------------------------------------------------------------------------ 633 //------------------------------------------------------------------------------
632 // Wrapper toward WebPINewDecoder 634 // Wrapper toward WebPINewDecoder
633 635
634 WebPIDecoder* WebPINewRGB(WEBP_CSP_MODE mode, uint8_t* output_buffer, 636 WebPIDecoder* WebPINewRGB(WEBP_CSP_MODE mode, uint8_t* output_buffer,
635 size_t output_buffer_size, int output_stride) { 637 size_t output_buffer_size, int output_stride) {
636 const int is_external_memory = (output_buffer != NULL); 638 const int is_external_memory = (output_buffer != NULL);
637 WebPIDecoder* idec; 639 WebPIDecoder* idec;
638 640
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 } 842 }
841 843
842 idec->io_.put = put; 844 idec->io_.put = put;
843 idec->io_.setup = setup; 845 idec->io_.setup = setup;
844 idec->io_.teardown = teardown; 846 idec->io_.teardown = teardown;
845 idec->io_.opaque = user_data; 847 idec->io_.opaque = user_data;
846 848
847 return 1; 849 return 1;
848 } 850 }
849 851
OLDNEW
« no previous file with comments | « third_party/libwebp/dec/frame.c ('k') | third_party/libwebp/dec/io.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698