Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 Google Inc. All Rights Reserved. | 1 // Copyright 2012 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 // WebP container demux. | 10 // WebP container demux. |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 40 } MemBuffer; | 40 } MemBuffer; |
| 41 | 41 |
| 42 typedef struct { | 42 typedef struct { |
| 43 size_t offset_; | 43 size_t offset_; |
| 44 size_t size_; | 44 size_t size_; |
| 45 } ChunkData; | 45 } ChunkData; |
| 46 | 46 |
| 47 typedef struct Frame { | 47 typedef struct Frame { |
| 48 int x_offset_, y_offset_; | 48 int x_offset_, y_offset_; |
| 49 int width_, height_; | 49 int width_, height_; |
| 50 int has_alpha_; | |
| 50 int duration_; | 51 int duration_; |
| 51 WebPMuxAnimDispose dispose_method_; | 52 WebPMuxAnimDispose dispose_method_; |
| 53 WebPMuxAnimBlend blend_method_; | |
| 52 int is_fragment_; // this is a frame fragment (and not a full frame). | 54 int is_fragment_; // this is a frame fragment (and not a full frame). |
| 53 int frame_num_; // the referent frame number for use in assembling fragments. | 55 int frame_num_; // the referent frame number for use in assembling fragments. |
| 54 int complete_; // img_components_ contains a full image. | 56 int complete_; // img_components_ contains a full image. |
| 55 ChunkData img_components_[2]; // 0=VP8{,L} 1=ALPH | 57 ChunkData img_components_[2]; // 0=VP8{,L} 1=ALPH |
| 56 struct Frame* next_; | 58 struct Frame* next_; |
| 57 } Frame; | 59 } Frame; |
| 58 | 60 |
| 59 typedef struct Chunk { | 61 typedef struct Chunk { |
| 60 ChunkData data_; | 62 ChunkData data_; |
| 61 struct Chunk* next_; | 63 struct Chunk* next_; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 189 const Frame* const last_frame = *dmux->frames_tail_; | 191 const Frame* const last_frame = *dmux->frames_tail_; |
| 190 if (last_frame != NULL && !last_frame->complete_) return 0; | 192 if (last_frame != NULL && !last_frame->complete_) return 0; |
| 191 | 193 |
| 192 *dmux->frames_tail_ = frame; | 194 *dmux->frames_tail_ = frame; |
| 193 frame->next_ = NULL; | 195 frame->next_ = NULL; |
| 194 dmux->frames_tail_ = &frame->next_; | 196 dmux->frames_tail_ = &frame->next_; |
| 195 return 1; | 197 return 1; |
| 196 } | 198 } |
| 197 | 199 |
| 198 // Store image bearing chunks to 'frame'. | 200 // Store image bearing chunks to 'frame'. |
| 199 // If 'has_vp8l_alpha' is not NULL, it will be set to true if the frame is a | |
| 200 // lossless image with alpha. | |
| 201 static ParseStatus StoreFrame(int frame_num, uint32_t min_size, | 201 static ParseStatus StoreFrame(int frame_num, uint32_t min_size, |
| 202 MemBuffer* const mem, Frame* const frame, | 202 MemBuffer* const mem, Frame* const frame) { |
| 203 int* const has_vp8l_alpha) { | |
| 204 int alpha_chunks = 0; | 203 int alpha_chunks = 0; |
| 205 int image_chunks = 0; | 204 int image_chunks = 0; |
| 206 int done = (MemDataSize(mem) < min_size); | 205 int done = (MemDataSize(mem) < min_size); |
| 207 ParseStatus status = PARSE_OK; | 206 ParseStatus status = PARSE_OK; |
| 208 | 207 |
| 209 if (has_vp8l_alpha != NULL) *has_vp8l_alpha = 0; // Default. | |
| 210 | |
| 211 if (done) return PARSE_NEED_MORE_DATA; | 208 if (done) return PARSE_NEED_MORE_DATA; |
| 212 | 209 |
| 213 do { | 210 do { |
| 214 const size_t chunk_start_offset = mem->start_; | 211 const size_t chunk_start_offset = mem->start_; |
| 215 const uint32_t fourcc = ReadLE32(mem); | 212 const uint32_t fourcc = ReadLE32(mem); |
| 216 const uint32_t payload_size = ReadLE32(mem); | 213 const uint32_t payload_size = ReadLE32(mem); |
| 217 const uint32_t payload_size_padded = payload_size + (payload_size & 1); | 214 const uint32_t payload_size_padded = payload_size + (payload_size & 1); |
| 218 const size_t payload_available = (payload_size_padded > MemDataSize(mem)) | 215 const size_t payload_available = (payload_size_padded > MemDataSize(mem)) |
| 219 ? MemDataSize(mem) : payload_size_padded; | 216 ? MemDataSize(mem) : payload_size_padded; |
| 220 const size_t chunk_size = CHUNK_HEADER_SIZE + payload_available; | 217 const size_t chunk_size = CHUNK_HEADER_SIZE + payload_available; |
| 221 | 218 |
| 222 if (payload_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; | 219 if (payload_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; |
| 223 if (SizeIsInvalid(mem, payload_size_padded)) return PARSE_ERROR; | 220 if (SizeIsInvalid(mem, payload_size_padded)) return PARSE_ERROR; |
| 224 if (payload_size_padded > MemDataSize(mem)) status = PARSE_NEED_MORE_DATA; | 221 if (payload_size_padded > MemDataSize(mem)) status = PARSE_NEED_MORE_DATA; |
| 225 | 222 |
| 226 switch (fourcc) { | 223 switch (fourcc) { |
| 227 case MKFOURCC('A', 'L', 'P', 'H'): | 224 case MKFOURCC('A', 'L', 'P', 'H'): |
| 228 if (alpha_chunks == 0) { | 225 if (alpha_chunks == 0) { |
| 229 ++alpha_chunks; | 226 ++alpha_chunks; |
| 230 frame->img_components_[1].offset_ = chunk_start_offset; | 227 frame->img_components_[1].offset_ = chunk_start_offset; |
| 231 frame->img_components_[1].size_ = chunk_size; | 228 frame->img_components_[1].size_ = chunk_size; |
| 229 frame->has_alpha_ = 1; | |
| 232 frame->frame_num_ = frame_num; | 230 frame->frame_num_ = frame_num; |
| 233 Skip(mem, payload_available); | 231 Skip(mem, payload_available); |
| 234 } else { | 232 } else { |
| 235 goto Done; | 233 goto Done; |
| 236 } | 234 } |
| 237 break; | 235 break; |
| 238 case MKFOURCC('V', 'P', '8', 'L'): | 236 case MKFOURCC('V', 'P', '8', 'L'): |
| 239 if (alpha_chunks > 0) return PARSE_ERROR; // VP8L has its own alpha | 237 if (alpha_chunks > 0) return PARSE_ERROR; // VP8L has its own alpha |
| 240 // fall through | 238 // fall through |
| 241 case MKFOURCC('V', 'P', '8', ' '): | 239 case MKFOURCC('V', 'P', '8', ' '): |
| 242 if (image_chunks == 0) { | 240 if (image_chunks == 0) { |
| 243 // Extract the bitstream features, tolerating failures when the data | 241 // Extract the bitstream features, tolerating failures when the data |
| 244 // is incomplete. | 242 // is incomplete. |
| 245 WebPBitstreamFeatures features; | 243 WebPBitstreamFeatures features; |
| 246 const VP8StatusCode vp8_status = | 244 const VP8StatusCode vp8_status = |
| 247 WebPGetFeatures(mem->buf_ + chunk_start_offset, chunk_size, | 245 WebPGetFeatures(mem->buf_ + chunk_start_offset, chunk_size, |
| 248 &features); | 246 &features); |
| 249 if (status == PARSE_NEED_MORE_DATA && | 247 if (status == PARSE_NEED_MORE_DATA && |
| 250 vp8_status == VP8_STATUS_NOT_ENOUGH_DATA) { | 248 vp8_status == VP8_STATUS_NOT_ENOUGH_DATA) { |
| 251 return PARSE_NEED_MORE_DATA; | 249 return PARSE_NEED_MORE_DATA; |
| 252 } else if (vp8_status != VP8_STATUS_OK) { | 250 } else if (vp8_status != VP8_STATUS_OK) { |
| 253 // We have enough data, and yet WebPGetFeatures() failed. | 251 // We have enough data, and yet WebPGetFeatures() failed. |
| 254 return PARSE_ERROR; | 252 return PARSE_ERROR; |
| 255 } | 253 } |
| 256 ++image_chunks; | 254 ++image_chunks; |
| 257 frame->img_components_[0].offset_ = chunk_start_offset; | 255 frame->img_components_[0].offset_ = chunk_start_offset; |
| 258 frame->img_components_[0].size_ = chunk_size; | 256 frame->img_components_[0].size_ = chunk_size; |
| 259 frame->width_ = features.width; | 257 frame->width_ = features.width; |
| 260 frame->height_ = features.height; | 258 frame->height_ = features.height; |
| 261 if (has_vp8l_alpha != NULL) *has_vp8l_alpha = features.has_alpha; | 259 frame->has_alpha_ |= features.has_alpha; |
|
fbarchard
2013/08/21 02:00:13
if you dont check the pointer, to enable alpha, th
urvang (Google)
2013/08/21 02:16:51
Nope. StoreFrame() is a static method, so 'frame'
| |
| 262 frame->frame_num_ = frame_num; | 260 frame->frame_num_ = frame_num; |
| 263 frame->complete_ = (status == PARSE_OK); | 261 frame->complete_ = (status == PARSE_OK); |
| 264 Skip(mem, payload_available); | 262 Skip(mem, payload_available); |
| 265 } else { | 263 } else { |
| 266 goto Done; | 264 goto Done; |
| 267 } | 265 } |
| 268 break; | 266 break; |
| 269 Done: | 267 Done: |
| 270 default: | 268 default: |
| 271 // Restore fourcc/size when moving up one level in parsing. | 269 // Restore fourcc/size when moving up one level in parsing. |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 299 return (*frame == NULL) ? PARSE_ERROR : PARSE_OK; | 297 return (*frame == NULL) ? PARSE_ERROR : PARSE_OK; |
| 300 } | 298 } |
| 301 | 299 |
| 302 // Parse a 'ANMF' chunk and any image bearing chunks that immediately follow. | 300 // Parse a 'ANMF' chunk and any image bearing chunks that immediately follow. |
| 303 // 'frame_chunk_size' is the previously validated, padded chunk size. | 301 // 'frame_chunk_size' is the previously validated, padded chunk size. |
| 304 static ParseStatus ParseAnimationFrame( | 302 static ParseStatus ParseAnimationFrame( |
| 305 WebPDemuxer* const dmux, uint32_t frame_chunk_size) { | 303 WebPDemuxer* const dmux, uint32_t frame_chunk_size) { |
| 306 const int has_frames = !!(dmux->feature_flags_ & ANIMATION_FLAG); | 304 const int has_frames = !!(dmux->feature_flags_ & ANIMATION_FLAG); |
| 307 const uint32_t anmf_payload_size = frame_chunk_size - ANMF_CHUNK_SIZE; | 305 const uint32_t anmf_payload_size = frame_chunk_size - ANMF_CHUNK_SIZE; |
| 308 int added_frame = 0; | 306 int added_frame = 0; |
| 307 int bits; | |
| 309 MemBuffer* const mem = &dmux->mem_; | 308 MemBuffer* const mem = &dmux->mem_; |
| 310 Frame* frame; | 309 Frame* frame; |
| 311 ParseStatus status = | 310 ParseStatus status = |
| 312 NewFrame(mem, ANMF_CHUNK_SIZE, frame_chunk_size, &frame); | 311 NewFrame(mem, ANMF_CHUNK_SIZE, frame_chunk_size, &frame); |
| 313 if (status != PARSE_OK) return status; | 312 if (status != PARSE_OK) return status; |
| 314 | 313 |
| 315 frame->x_offset_ = 2 * ReadLE24s(mem); | 314 frame->x_offset_ = 2 * ReadLE24s(mem); |
| 316 frame->y_offset_ = 2 * ReadLE24s(mem); | 315 frame->y_offset_ = 2 * ReadLE24s(mem); |
| 317 frame->width_ = 1 + ReadLE24s(mem); | 316 frame->width_ = 1 + ReadLE24s(mem); |
| 318 frame->height_ = 1 + ReadLE24s(mem); | 317 frame->height_ = 1 + ReadLE24s(mem); |
| 319 frame->duration_ = ReadLE24s(mem); | 318 frame->duration_ = ReadLE24s(mem); |
| 320 frame->dispose_method_ = (WebPMuxAnimDispose)(ReadByte(mem) & 1); | 319 bits = ReadByte(mem); |
| 320 frame->dispose_method_ = | |
| 321 (bits & 1) ? WEBP_MUX_DISPOSE_BACKGROUND : WEBP_MUX_DISPOSE_NONE; | |
| 322 frame->blend_method_ = (bits & 2) ? WEBP_MUX_NO_BLEND : WEBP_MUX_BLEND; | |
| 321 if (frame->width_ * (uint64_t)frame->height_ >= MAX_IMAGE_AREA) { | 323 if (frame->width_ * (uint64_t)frame->height_ >= MAX_IMAGE_AREA) { |
| 322 free(frame); | 324 free(frame); |
| 323 return PARSE_ERROR; | 325 return PARSE_ERROR; |
| 324 } | 326 } |
| 325 | 327 |
| 326 // Store a frame only if the animation flag is set there is some data for | 328 // Store a frame only if the animation flag is set there is some data for |
| 327 // this frame is available. | 329 // this frame is available. |
| 328 status = StoreFrame(dmux->num_frames_ + 1, anmf_payload_size, mem, frame, | 330 status = StoreFrame(dmux->num_frames_ + 1, anmf_payload_size, mem, frame); |
| 329 NULL); | |
| 330 if (status != PARSE_ERROR && has_frames && frame->frame_num_ > 0) { | 331 if (status != PARSE_ERROR && has_frames && frame->frame_num_ > 0) { |
| 331 added_frame = AddFrame(dmux, frame); | 332 added_frame = AddFrame(dmux, frame); |
| 332 if (added_frame) { | 333 if (added_frame) { |
| 333 ++dmux->num_frames_; | 334 ++dmux->num_frames_; |
| 334 } else { | 335 } else { |
| 335 status = PARSE_ERROR; | 336 status = PARSE_ERROR; |
| 336 } | 337 } |
| 337 } | 338 } |
| 338 | 339 |
| 339 if (!added_frame) free(frame); | 340 if (!added_frame) free(frame); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 354 ParseStatus status = | 355 ParseStatus status = |
| 355 NewFrame(mem, FRGM_CHUNK_SIZE, fragment_chunk_size, &frame); | 356 NewFrame(mem, FRGM_CHUNK_SIZE, fragment_chunk_size, &frame); |
| 356 if (status != PARSE_OK) return status; | 357 if (status != PARSE_OK) return status; |
| 357 | 358 |
| 358 frame->is_fragment_ = 1; | 359 frame->is_fragment_ = 1; |
| 359 frame->x_offset_ = 2 * ReadLE24s(mem); | 360 frame->x_offset_ = 2 * ReadLE24s(mem); |
| 360 frame->y_offset_ = 2 * ReadLE24s(mem); | 361 frame->y_offset_ = 2 * ReadLE24s(mem); |
| 361 | 362 |
| 362 // Store a fragment only if the fragments flag is set there is some data for | 363 // Store a fragment only if the fragments flag is set there is some data for |
| 363 // this fragment is available. | 364 // this fragment is available. |
| 364 status = StoreFrame(frame_num, frgm_payload_size, mem, frame, NULL); | 365 status = StoreFrame(frame_num, frgm_payload_size, mem, frame); |
| 365 if (status != PARSE_ERROR && has_fragments && frame->frame_num_ > 0) { | 366 if (status != PARSE_ERROR && has_fragments && frame->frame_num_ > 0) { |
| 366 added_fragment = AddFrame(dmux, frame); | 367 added_fragment = AddFrame(dmux, frame); |
| 367 if (!added_fragment) { | 368 if (!added_fragment) { |
| 368 status = PARSE_ERROR; | 369 status = PARSE_ERROR; |
| 369 } else { | 370 } else { |
| 370 dmux->num_frames_ = 1; | 371 dmux->num_frames_ = 1; |
| 371 } | 372 } |
| 372 } | 373 } |
| 373 | 374 |
| 374 if (!added_fragment) free(frame); | 375 if (!added_fragment) free(frame); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 417 | 418 |
| 418 Skip(mem, RIFF_HEADER_SIZE); | 419 Skip(mem, RIFF_HEADER_SIZE); |
| 419 return 1; | 420 return 1; |
| 420 } | 421 } |
| 421 | 422 |
| 422 static ParseStatus ParseSingleImage(WebPDemuxer* const dmux) { | 423 static ParseStatus ParseSingleImage(WebPDemuxer* const dmux) { |
| 423 const size_t min_size = CHUNK_HEADER_SIZE; | 424 const size_t min_size = CHUNK_HEADER_SIZE; |
| 424 MemBuffer* const mem = &dmux->mem_; | 425 MemBuffer* const mem = &dmux->mem_; |
| 425 Frame* frame; | 426 Frame* frame; |
| 426 ParseStatus status; | 427 ParseStatus status; |
| 427 int has_vp8l_alpha = 0; // Frame contains a lossless image with alpha. | |
| 428 | 428 |
| 429 if (dmux->frames_ != NULL) return PARSE_ERROR; | 429 if (dmux->frames_ != NULL) return PARSE_ERROR; |
| 430 if (SizeIsInvalid(mem, min_size)) return PARSE_ERROR; | 430 if (SizeIsInvalid(mem, min_size)) return PARSE_ERROR; |
| 431 if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA; | 431 if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA; |
| 432 | 432 |
| 433 frame = (Frame*)calloc(1, sizeof(*frame)); | 433 frame = (Frame*)calloc(1, sizeof(*frame)); |
| 434 if (frame == NULL) return PARSE_ERROR; | 434 if (frame == NULL) return PARSE_ERROR; |
| 435 | 435 |
| 436 // For the single image case we allow parsing of a partial frame, but we need | 436 // For the single image case we allow parsing of a partial frame, but we need |
| 437 // at least CHUNK_HEADER_SIZE for parsing. | 437 // at least CHUNK_HEADER_SIZE for parsing. |
| 438 status = StoreFrame(1, CHUNK_HEADER_SIZE, &dmux->mem_, frame, | 438 status = StoreFrame(1, CHUNK_HEADER_SIZE, &dmux->mem_, frame); |
| 439 &has_vp8l_alpha); | |
| 440 if (status != PARSE_ERROR) { | 439 if (status != PARSE_ERROR) { |
| 441 const int has_alpha = !!(dmux->feature_flags_ & ALPHA_FLAG); | 440 const int has_alpha = !!(dmux->feature_flags_ & ALPHA_FLAG); |
| 442 // Clear any alpha when the alpha flag is missing. | 441 // Clear any alpha when the alpha flag is missing. |
| 443 if (!has_alpha && frame->img_components_[1].size_ > 0) { | 442 if (!has_alpha && frame->img_components_[1].size_ > 0) { |
| 444 frame->img_components_[1].offset_ = 0; | 443 frame->img_components_[1].offset_ = 0; |
| 445 frame->img_components_[1].size_ = 0; | 444 frame->img_components_[1].size_ = 0; |
| 445 frame->has_alpha_ = 0; | |
| 446 } | 446 } |
| 447 | 447 |
| 448 // Use the frame width/height as the canvas values for non-vp8x files. | 448 // Use the frame width/height as the canvas values for non-vp8x files. |
| 449 // Also, set ALPHA_FLAG if this is a lossless image with alpha. | 449 // Also, set ALPHA_FLAG if this is a lossless image with alpha. |
| 450 if (!dmux->is_ext_format_ && frame->width_ > 0 && frame->height_ > 0) { | 450 if (!dmux->is_ext_format_ && frame->width_ > 0 && frame->height_ > 0) { |
| 451 dmux->state_ = WEBP_DEMUX_PARSED_HEADER; | 451 dmux->state_ = WEBP_DEMUX_PARSED_HEADER; |
| 452 dmux->canvas_width_ = frame->width_; | 452 dmux->canvas_width_ = frame->width_; |
| 453 dmux->canvas_height_ = frame->height_; | 453 dmux->canvas_height_ = frame->height_; |
| 454 dmux->feature_flags_ |= has_vp8l_alpha ? ALPHA_FLAG : 0; | 454 dmux->feature_flags_ |= frame->has_alpha_ ? ALPHA_FLAG : 0; |
| 455 } | 455 } |
| 456 AddFrame(dmux, frame); | 456 AddFrame(dmux, frame); |
| 457 dmux->num_frames_ = 1; | 457 dmux->num_frames_ = 1; |
| 458 } else { | 458 } else { |
| 459 free(frame); | 459 free(frame); |
| 460 } | 460 } |
| 461 | 461 |
| 462 return status; | 462 return status; |
| 463 } | 463 } |
| 464 | 464 |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 829 assert(first_frame != NULL); | 829 assert(first_frame != NULL); |
| 830 | 830 |
| 831 iter->frame_num = first_frame->frame_num_; | 831 iter->frame_num = first_frame->frame_num_; |
| 832 iter->num_frames = dmux->num_frames_; | 832 iter->num_frames = dmux->num_frames_; |
| 833 iter->fragment_num = fragment_num; | 833 iter->fragment_num = fragment_num; |
| 834 iter->num_fragments = num_fragments; | 834 iter->num_fragments = num_fragments; |
| 835 iter->x_offset = fragment->x_offset_; | 835 iter->x_offset = fragment->x_offset_; |
| 836 iter->y_offset = fragment->y_offset_; | 836 iter->y_offset = fragment->y_offset_; |
| 837 iter->width = fragment->width_; | 837 iter->width = fragment->width_; |
| 838 iter->height = fragment->height_; | 838 iter->height = fragment->height_; |
| 839 iter->has_alpha = fragment->has_alpha_; | |
| 839 iter->duration = fragment->duration_; | 840 iter->duration = fragment->duration_; |
| 840 iter->dispose_method = fragment->dispose_method_; | 841 iter->dispose_method = fragment->dispose_method_; |
| 842 iter->blend_method = fragment->blend_method_; | |
| 841 iter->complete = fragment->complete_; | 843 iter->complete = fragment->complete_; |
| 842 iter->fragment.bytes = payload; | 844 iter->fragment.bytes = payload; |
| 843 iter->fragment.size = payload_size; | 845 iter->fragment.size = payload_size; |
| 844 // TODO(jzern): adjust offsets for 'FRGM's embedded in 'ANMF's | 846 // TODO(jzern): adjust offsets for 'FRGM's embedded in 'ANMF's |
| 845 return 1; | 847 return 1; |
| 846 } | 848 } |
| 847 | 849 |
| 848 static int SetFrame(int frame_num, WebPIterator* const iter) { | 850 static int SetFrame(int frame_num, WebPIterator* const iter) { |
| 849 const Frame* frame; | 851 const Frame* frame; |
| 850 const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_; | 852 const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 969 return 0; | 971 return 0; |
| 970 } | 972 } |
| 971 | 973 |
| 972 void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter) { | 974 void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter) { |
| 973 (void)iter; | 975 (void)iter; |
| 974 } | 976 } |
| 975 | 977 |
| 976 #if defined(__cplusplus) || defined(c_plusplus) | 978 #if defined(__cplusplus) || defined(c_plusplus) |
| 977 } // extern "C" | 979 } // extern "C" |
| 978 #endif | 980 #endif |
| OLD | NEW |