mirror of
				https://github.com/webmproject/libwebp.git
				synced 2025-10-31 18:35:41 +01:00 
			
		
		
		
	demux,cosmetics: rm struct member '_' suffix
This is a follow up to:
ee8e8c62 Fix member naming for VP8LHistogram
This better matches Google style and clears some clang-tidy warnings.
Change-Id: Ida41ca82445800552573ff5ebbde743cf8fa6eff
			
			
This commit is contained in:
		| @@ -39,18 +39,18 @@ static void BlendPixelRowPremult(uint32_t* const src, const uint32_t* const dst, | |||||||
|                                  int num_pixels); |                                  int num_pixels); | ||||||
|  |  | ||||||
| struct WebPAnimDecoder { | struct WebPAnimDecoder { | ||||||
|   WebPDemuxer* demux_;             // Demuxer created from given WebP bitstream. |   WebPDemuxer* demux;              // Demuxer created from given WebP bitstream. | ||||||
|   WebPDecoderConfig config_;       // Decoder config. |   WebPDecoderConfig config;        // Decoder config. | ||||||
|   // Note: we use a pointer to a function blending multiple pixels at a time to |   // Note: we use a pointer to a function blending multiple pixels at a time to | ||||||
|   // allow possible inlining of per-pixel blending function. |   // allow possible inlining of per-pixel blending function. | ||||||
|   BlendRowFunc blend_func_;        // Pointer to the chose blend row function. |   BlendRowFunc blend_func;         // Pointer to the chose blend row function. | ||||||
|   WebPAnimInfo info_;              // Global info about the animation. |   WebPAnimInfo info;               // Global info about the animation. | ||||||
|   uint8_t* curr_frame_;            // Current canvas (not disposed). |   uint8_t* curr_frame;             // Current canvas (not disposed). | ||||||
|   uint8_t* prev_frame_disposed_;   // Previous canvas (properly disposed). |   uint8_t* prev_frame_disposed;    // Previous canvas (properly disposed). | ||||||
|   int prev_frame_timestamp_;       // Previous frame timestamp (milliseconds). |   int prev_frame_timestamp;        // Previous frame timestamp (milliseconds). | ||||||
|   WebPIterator prev_iter_;         // Iterator object for previous frame. |   WebPIterator prev_iter;          // Iterator object for previous frame. | ||||||
|   int prev_frame_was_keyframe_;    // True if previous frame was a keyframe. |   int prev_frame_was_keyframe;     // True if previous frame was a keyframe. | ||||||
|   int next_frame_;                 // Index of the next frame to be decoded |   int next_frame;                  // Index of the next frame to be decoded | ||||||
|                                    // (starting from 1). |                                    // (starting from 1). | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -73,7 +73,7 @@ WEBP_NODISCARD static int ApplyDecoderOptions( | |||||||
|     const WebPAnimDecoderOptions* const dec_options, |     const WebPAnimDecoderOptions* const dec_options, | ||||||
|     WebPAnimDecoder* const dec) { |     WebPAnimDecoder* const dec) { | ||||||
|   WEBP_CSP_MODE mode; |   WEBP_CSP_MODE mode; | ||||||
|   WebPDecoderConfig* config = &dec->config_; |   WebPDecoderConfig* config = &dec->config; | ||||||
|   assert(dec_options != NULL); |   assert(dec_options != NULL); | ||||||
|  |  | ||||||
|   mode = dec_options->color_mode; |   mode = dec_options->color_mode; | ||||||
| @@ -81,7 +81,7 @@ WEBP_NODISCARD static int ApplyDecoderOptions( | |||||||
|       mode != MODE_rgbA && mode != MODE_bgrA) { |       mode != MODE_rgbA && mode != MODE_bgrA) { | ||||||
|     return 0; |     return 0; | ||||||
|   } |   } | ||||||
|   dec->blend_func_ = (mode == MODE_RGBA || mode == MODE_BGRA) |   dec->blend_func = (mode == MODE_RGBA || mode == MODE_BGRA) | ||||||
|                         ? &BlendPixelRowNonPremult |                         ? &BlendPixelRowNonPremult | ||||||
|                         : &BlendPixelRowPremult; |                         : &BlendPixelRowPremult; | ||||||
|   if (!WebPInitDecoderConfig(config)) { |   if (!WebPInitDecoderConfig(config)) { | ||||||
| @@ -123,22 +123,22 @@ WebPAnimDecoder* WebPAnimDecoderNewInternal( | |||||||
|   } |   } | ||||||
|   if (!ApplyDecoderOptions(&options, dec)) goto Error; |   if (!ApplyDecoderOptions(&options, dec)) goto Error; | ||||||
|  |  | ||||||
|   dec->demux_ = WebPDemux(webp_data); |   dec->demux = WebPDemux(webp_data); | ||||||
|   if (dec->demux_ == NULL) goto Error; |   if (dec->demux == NULL) goto Error; | ||||||
|  |  | ||||||
|   dec->info_.canvas_width = WebPDemuxGetI(dec->demux_, WEBP_FF_CANVAS_WIDTH); |   dec->info.canvas_width = WebPDemuxGetI(dec->demux, WEBP_FF_CANVAS_WIDTH); | ||||||
|   dec->info_.canvas_height = WebPDemuxGetI(dec->demux_, WEBP_FF_CANVAS_HEIGHT); |   dec->info.canvas_height = WebPDemuxGetI(dec->demux, WEBP_FF_CANVAS_HEIGHT); | ||||||
|   dec->info_.loop_count = WebPDemuxGetI(dec->demux_, WEBP_FF_LOOP_COUNT); |   dec->info.loop_count = WebPDemuxGetI(dec->demux, WEBP_FF_LOOP_COUNT); | ||||||
|   dec->info_.bgcolor = WebPDemuxGetI(dec->demux_, WEBP_FF_BACKGROUND_COLOR); |   dec->info.bgcolor = WebPDemuxGetI(dec->demux, WEBP_FF_BACKGROUND_COLOR); | ||||||
|   dec->info_.frame_count = WebPDemuxGetI(dec->demux_, WEBP_FF_FRAME_COUNT); |   dec->info.frame_count = WebPDemuxGetI(dec->demux, WEBP_FF_FRAME_COUNT); | ||||||
|  |  | ||||||
|   // Note: calloc() because we fill frame with zeroes as well. |   // Note: calloc() because we fill frame with zeroes as well. | ||||||
|   dec->curr_frame_ = (uint8_t*)WebPSafeCalloc( |   dec->curr_frame = (uint8_t*)WebPSafeCalloc( | ||||||
|       dec->info_.canvas_width * NUM_CHANNELS, dec->info_.canvas_height); |       dec->info.canvas_width * NUM_CHANNELS, dec->info.canvas_height); | ||||||
|   if (dec->curr_frame_ == NULL) goto Error; |   if (dec->curr_frame == NULL) goto Error; | ||||||
|   dec->prev_frame_disposed_ = (uint8_t*)WebPSafeCalloc( |   dec->prev_frame_disposed = (uint8_t*)WebPSafeCalloc( | ||||||
|       dec->info_.canvas_width * NUM_CHANNELS, dec->info_.canvas_height); |       dec->info.canvas_width * NUM_CHANNELS, dec->info.canvas_height); | ||||||
|   if (dec->prev_frame_disposed_ == NULL) goto Error; |   if (dec->prev_frame_disposed == NULL) goto Error; | ||||||
|  |  | ||||||
|   WebPAnimDecoderReset(dec); |   WebPAnimDecoderReset(dec); | ||||||
|   return dec; |   return dec; | ||||||
| @@ -150,7 +150,7 @@ WebPAnimDecoder* WebPAnimDecoderNewInternal( | |||||||
|  |  | ||||||
| int WebPAnimDecoderGetInfo(const WebPAnimDecoder* dec, WebPAnimInfo* info) { | int WebPAnimDecoderGetInfo(const WebPAnimDecoder* dec, WebPAnimInfo* info) { | ||||||
|   if (dec == NULL || info == NULL) return 0; |   if (dec == NULL || info == NULL) return 0; | ||||||
|   *info = dec->info_; |   *info = dec->info; | ||||||
|   return 1; |   return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -338,25 +338,25 @@ int WebPAnimDecoderGetNext(WebPAnimDecoder* dec, | |||||||
|   if (dec == NULL || buf_ptr == NULL || timestamp_ptr == NULL) return 0; |   if (dec == NULL || buf_ptr == NULL || timestamp_ptr == NULL) return 0; | ||||||
|   if (!WebPAnimDecoderHasMoreFrames(dec)) return 0; |   if (!WebPAnimDecoderHasMoreFrames(dec)) return 0; | ||||||
|  |  | ||||||
|   width = dec->info_.canvas_width; |   width = dec->info.canvas_width; | ||||||
|   height = dec->info_.canvas_height; |   height = dec->info.canvas_height; | ||||||
|   blend_row = dec->blend_func_; |   blend_row = dec->blend_func; | ||||||
|  |  | ||||||
|   // Get compressed frame. |   // Get compressed frame. | ||||||
|   if (!WebPDemuxGetFrame(dec->demux_, dec->next_frame_, &iter)) { |   if (!WebPDemuxGetFrame(dec->demux, dec->next_frame, &iter)) { | ||||||
|     return 0; |     return 0; | ||||||
|   } |   } | ||||||
|   timestamp = dec->prev_frame_timestamp_ + iter.duration; |   timestamp = dec->prev_frame_timestamp + iter.duration; | ||||||
|  |  | ||||||
|   // Initialize. |   // Initialize. | ||||||
|   is_key_frame = IsKeyFrame(&iter, &dec->prev_iter_, |   is_key_frame = IsKeyFrame(&iter, &dec->prev_iter, | ||||||
|                             dec->prev_frame_was_keyframe_, width, height); |                             dec->prev_frame_was_keyframe, width, height); | ||||||
|   if (is_key_frame) { |   if (is_key_frame) { | ||||||
|     if (!ZeroFillCanvas(dec->curr_frame_, width, height)) { |     if (!ZeroFillCanvas(dec->curr_frame, width, height)) { | ||||||
|       goto Error; |       goto Error; | ||||||
|     } |     } | ||||||
|   } else { |   } else { | ||||||
|     if (!CopyCanvas(dec->prev_frame_disposed_, dec->curr_frame_, |     if (!CopyCanvas(dec->prev_frame_disposed, dec->curr_frame, | ||||||
|                     width, height)) { |                     width, height)) { | ||||||
|       goto Error; |       goto Error; | ||||||
|     } |     } | ||||||
| @@ -370,12 +370,12 @@ int WebPAnimDecoderGetNext(WebPAnimDecoder* dec, | |||||||
|     const uint64_t out_offset = (uint64_t)iter.y_offset * stride + |     const uint64_t out_offset = (uint64_t)iter.y_offset * stride + | ||||||
|                                 (uint64_t)iter.x_offset * NUM_CHANNELS;  // 53b |                                 (uint64_t)iter.x_offset * NUM_CHANNELS;  // 53b | ||||||
|     const uint64_t size = (uint64_t)iter.height * stride;  // at most 25 + 27b |     const uint64_t size = (uint64_t)iter.height * stride;  // at most 25 + 27b | ||||||
|     WebPDecoderConfig* const config = &dec->config_; |     WebPDecoderConfig* const config = &dec->config; | ||||||
|     WebPRGBABuffer* const buf = &config->output.u.RGBA; |     WebPRGBABuffer* const buf = &config->output.u.RGBA; | ||||||
|     if ((size_t)size != size) goto Error; |     if ((size_t)size != size) goto Error; | ||||||
|     buf->stride = (int)stride; |     buf->stride = (int)stride; | ||||||
|     buf->size = (size_t)size; |     buf->size = (size_t)size; | ||||||
|     buf->rgba = dec->curr_frame_ + out_offset; |     buf->rgba = dec->curr_frame + out_offset; | ||||||
|  |  | ||||||
|     if (WebPDecode(in, in_size, config) != VP8_STATUS_OK) { |     if (WebPDecode(in, in_size, config) != VP8_STATUS_OK) { | ||||||
|       goto Error; |       goto Error; | ||||||
| @@ -388,18 +388,18 @@ int WebPAnimDecoderGetNext(WebPAnimDecoder* dec, | |||||||
|   // that pixel in the previous frame if blending method of is WEBP_MUX_BLEND. |   // that pixel in the previous frame if blending method of is WEBP_MUX_BLEND. | ||||||
|   if (iter.frame_num > 1 && iter.blend_method == WEBP_MUX_BLEND && |   if (iter.frame_num > 1 && iter.blend_method == WEBP_MUX_BLEND && | ||||||
|       !is_key_frame) { |       !is_key_frame) { | ||||||
|     if (dec->prev_iter_.dispose_method == WEBP_MUX_DISPOSE_NONE) { |     if (dec->prev_iter.dispose_method == WEBP_MUX_DISPOSE_NONE) { | ||||||
|       int y; |       int y; | ||||||
|       // Blend transparent pixels with pixels in previous canvas. |       // Blend transparent pixels with pixels in previous canvas. | ||||||
|       for (y = 0; y < iter.height; ++y) { |       for (y = 0; y < iter.height; ++y) { | ||||||
|         const size_t offset = |         const size_t offset = | ||||||
|             (iter.y_offset + y) * width + iter.x_offset; |             (iter.y_offset + y) * width + iter.x_offset; | ||||||
|         blend_row((uint32_t*)dec->curr_frame_ + offset, |         blend_row((uint32_t*)dec->curr_frame + offset, | ||||||
|                   (uint32_t*)dec->prev_frame_disposed_ + offset, iter.width); |                   (uint32_t*)dec->prev_frame_disposed + offset, iter.width); | ||||||
|       } |       } | ||||||
|     } else { |     } else { | ||||||
|       int y; |       int y; | ||||||
|       assert(dec->prev_iter_.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND); |       assert(dec->prev_iter.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND); | ||||||
|       // We need to blend a transparent pixel with its value just after |       // We need to blend a transparent pixel with its value just after | ||||||
|       // initialization. That is, blend it with: |       // initialization. That is, blend it with: | ||||||
|       // * Fully transparent pixel if it belongs to prevRect <-- No-op. |       // * Fully transparent pixel if it belongs to prevRect <-- No-op. | ||||||
| @@ -407,39 +407,39 @@ int WebPAnimDecoderGetNext(WebPAnimDecoder* dec, | |||||||
|       for (y = 0; y < iter.height; ++y) { |       for (y = 0; y < iter.height; ++y) { | ||||||
|         const int canvas_y = iter.y_offset + y; |         const int canvas_y = iter.y_offset + y; | ||||||
|         int left1, width1, left2, width2; |         int left1, width1, left2, width2; | ||||||
|         FindBlendRangeAtRow(&iter, &dec->prev_iter_, canvas_y, &left1, &width1, |         FindBlendRangeAtRow(&iter, &dec->prev_iter, canvas_y, &left1, &width1, | ||||||
|                             &left2, &width2); |                             &left2, &width2); | ||||||
|         if (width1 > 0) { |         if (width1 > 0) { | ||||||
|           const size_t offset1 = canvas_y * width + left1; |           const size_t offset1 = canvas_y * width + left1; | ||||||
|           blend_row((uint32_t*)dec->curr_frame_ + offset1, |           blend_row((uint32_t*)dec->curr_frame + offset1, | ||||||
|                     (uint32_t*)dec->prev_frame_disposed_ + offset1, width1); |                     (uint32_t*)dec->prev_frame_disposed + offset1, width1); | ||||||
|         } |         } | ||||||
|         if (width2 > 0) { |         if (width2 > 0) { | ||||||
|           const size_t offset2 = canvas_y * width + left2; |           const size_t offset2 = canvas_y * width + left2; | ||||||
|           blend_row((uint32_t*)dec->curr_frame_ + offset2, |           blend_row((uint32_t*)dec->curr_frame + offset2, | ||||||
|                     (uint32_t*)dec->prev_frame_disposed_ + offset2, width2); |                     (uint32_t*)dec->prev_frame_disposed + offset2, width2); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Update info of the previous frame and dispose it for the next iteration. |   // Update info of the previous frame and dispose it for the next iteration. | ||||||
|   dec->prev_frame_timestamp_ = timestamp; |   dec->prev_frame_timestamp = timestamp; | ||||||
|   WebPDemuxReleaseIterator(&dec->prev_iter_); |   WebPDemuxReleaseIterator(&dec->prev_iter); | ||||||
|   dec->prev_iter_ = iter; |   dec->prev_iter = iter; | ||||||
|   dec->prev_frame_was_keyframe_ = is_key_frame; |   dec->prev_frame_was_keyframe = is_key_frame; | ||||||
|   if (!CopyCanvas(dec->curr_frame_, dec->prev_frame_disposed_, width, height)) { |   if (!CopyCanvas(dec->curr_frame, dec->prev_frame_disposed, width, height)) { | ||||||
|     goto Error; |     goto Error; | ||||||
|   } |   } | ||||||
|   if (dec->prev_iter_.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) { |   if (dec->prev_iter.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) { | ||||||
|     ZeroFillFrameRect(dec->prev_frame_disposed_, width * NUM_CHANNELS, |     ZeroFillFrameRect(dec->prev_frame_disposed, width * NUM_CHANNELS, | ||||||
|                       dec->prev_iter_.x_offset, dec->prev_iter_.y_offset, |                       dec->prev_iter.x_offset, dec->prev_iter.y_offset, | ||||||
|                       dec->prev_iter_.width, dec->prev_iter_.height); |                       dec->prev_iter.width, dec->prev_iter.height); | ||||||
|   } |   } | ||||||
|   ++dec->next_frame_; |   ++dec->next_frame; | ||||||
|  |  | ||||||
|   // All OK, fill in the values. |   // All OK, fill in the values. | ||||||
|   *buf_ptr = dec->curr_frame_; |   *buf_ptr = dec->curr_frame; | ||||||
|   *timestamp_ptr = timestamp; |   *timestamp_ptr = timestamp; | ||||||
|   return 1; |   return 1; | ||||||
|  |  | ||||||
| @@ -450,30 +450,30 @@ int WebPAnimDecoderGetNext(WebPAnimDecoder* dec, | |||||||
|  |  | ||||||
| int WebPAnimDecoderHasMoreFrames(const WebPAnimDecoder* dec) { | int WebPAnimDecoderHasMoreFrames(const WebPAnimDecoder* dec) { | ||||||
|   if (dec == NULL) return 0; |   if (dec == NULL) return 0; | ||||||
|   return (dec->next_frame_ <= (int)dec->info_.frame_count); |   return (dec->next_frame <= (int)dec->info.frame_count); | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebPAnimDecoderReset(WebPAnimDecoder* dec) { | void WebPAnimDecoderReset(WebPAnimDecoder* dec) { | ||||||
|   if (dec != NULL) { |   if (dec != NULL) { | ||||||
|     dec->prev_frame_timestamp_ = 0; |     dec->prev_frame_timestamp = 0; | ||||||
|     WebPDemuxReleaseIterator(&dec->prev_iter_); |     WebPDemuxReleaseIterator(&dec->prev_iter); | ||||||
|     memset(&dec->prev_iter_, 0, sizeof(dec->prev_iter_)); |     memset(&dec->prev_iter, 0, sizeof(dec->prev_iter)); | ||||||
|     dec->prev_frame_was_keyframe_ = 0; |     dec->prev_frame_was_keyframe = 0; | ||||||
|     dec->next_frame_ = 1; |     dec->next_frame = 1; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| const WebPDemuxer* WebPAnimDecoderGetDemuxer(const WebPAnimDecoder* dec) { | const WebPDemuxer* WebPAnimDecoderGetDemuxer(const WebPAnimDecoder* dec) { | ||||||
|   if (dec == NULL) return NULL; |   if (dec == NULL) return NULL; | ||||||
|   return dec->demux_; |   return dec->demux; | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebPAnimDecoderDelete(WebPAnimDecoder* dec) { | void WebPAnimDecoderDelete(WebPAnimDecoder* dec) { | ||||||
|   if (dec != NULL) { |   if (dec != NULL) { | ||||||
|     WebPDemuxReleaseIterator(&dec->prev_iter_); |     WebPDemuxReleaseIterator(&dec->prev_iter); | ||||||
|     WebPDemuxDelete(dec->demux_); |     WebPDemuxDelete(dec->demux); | ||||||
|     WebPSafeFree(dec->curr_frame_); |     WebPSafeFree(dec->curr_frame); | ||||||
|     WebPSafeFree(dec->prev_frame_disposed_); |     WebPSafeFree(dec->prev_frame_disposed); | ||||||
|     WebPSafeFree(dec); |     WebPSafeFree(dec); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -28,49 +28,49 @@ | |||||||
| #define DMUX_REV_VERSION 0 | #define DMUX_REV_VERSION 0 | ||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
|   size_t start_;        // start location of the data |   size_t start;         // start location of the data | ||||||
|   size_t end_;          // end location |   size_t end;           // end location | ||||||
|   size_t riff_end_;     // riff chunk end location, can be > end_. |   size_t riff_end;      // riff chunk end location, can be > end. | ||||||
|   size_t buf_size_;     // size of the buffer |   size_t buf_size;      // size of the buffer | ||||||
|   const uint8_t* buf_; |   const uint8_t* buf; | ||||||
| } MemBuffer; | } MemBuffer; | ||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
|   size_t offset_; |   size_t offset; | ||||||
|   size_t size_; |   size_t size; | ||||||
| } ChunkData; | } ChunkData; | ||||||
|  |  | ||||||
| typedef struct Frame { | typedef struct Frame { | ||||||
|   int x_offset_, y_offset_; |   int x_offset, y_offset; | ||||||
|   int width_, height_; |   int width, height; | ||||||
|   int has_alpha_; |   int has_alpha; | ||||||
|   int duration_; |   int duration; | ||||||
|   WebPMuxAnimDispose dispose_method_; |   WebPMuxAnimDispose dispose_method; | ||||||
|   WebPMuxAnimBlend blend_method_; |   WebPMuxAnimBlend blend_method; | ||||||
|   int frame_num_; |   int frame_num; | ||||||
|   int complete_;   // img_components_ contains a full image. |   int complete;   // img_components contains a full image. | ||||||
|   ChunkData img_components_[2];  // 0=VP8{,L} 1=ALPH |   ChunkData img_components[2];  // 0=VP8{,L} 1=ALPH | ||||||
|   struct Frame* next_; |   struct Frame* next; | ||||||
| } Frame; | } Frame; | ||||||
|  |  | ||||||
| typedef struct Chunk { | typedef struct Chunk { | ||||||
|   ChunkData data_; |   ChunkData data; | ||||||
|   struct Chunk* next_; |   struct Chunk* next; | ||||||
| } Chunk; | } Chunk; | ||||||
|  |  | ||||||
| struct WebPDemuxer { | struct WebPDemuxer { | ||||||
|   MemBuffer mem_; |   MemBuffer mem; | ||||||
|   WebPDemuxState state_; |   WebPDemuxState state; | ||||||
|   int is_ext_format_; |   int is_ext_format; | ||||||
|   uint32_t feature_flags_; |   uint32_t feature_flags; | ||||||
|   int canvas_width_, canvas_height_; |   int canvas_width, canvas_height; | ||||||
|   int loop_count_; |   int loop_count; | ||||||
|   uint32_t bgcolor_; |   uint32_t bgcolor; | ||||||
|   int num_frames_; |   int num_frames; | ||||||
|   Frame* frames_; |   Frame* frames; | ||||||
|   Frame** frames_tail_; |   Frame** frames_tail; | ||||||
|   Chunk* chunks_;  // non-image chunks |   Chunk* chunks;  // non-image chunks | ||||||
|   Chunk** chunks_tail_; |   Chunk** chunks_tail; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| typedef enum { | typedef enum { | ||||||
| @@ -108,10 +108,10 @@ int WebPGetDemuxVersion(void) { | |||||||
|  |  | ||||||
| static int RemapMemBuffer(MemBuffer* const mem, | static int RemapMemBuffer(MemBuffer* const mem, | ||||||
|                           const uint8_t* data, size_t size) { |                           const uint8_t* data, size_t size) { | ||||||
|   if (size < mem->buf_size_) return 0;  // can't remap to a shorter buffer! |   if (size < mem->buf_size) return 0;  // can't remap to a shorter buffer! | ||||||
|  |  | ||||||
|   mem->buf_ = data; |   mem->buf = data; | ||||||
|   mem->end_ = mem->buf_size_ = size; |   mem->end = mem->buf_size = size; | ||||||
|   return 1; |   return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -123,49 +123,49 @@ static int InitMemBuffer(MemBuffer* const mem, | |||||||
|  |  | ||||||
| // Return the remaining data size available in 'mem'. | // Return the remaining data size available in 'mem'. | ||||||
| static WEBP_INLINE size_t MemDataSize(const MemBuffer* const mem) { | static WEBP_INLINE size_t MemDataSize(const MemBuffer* const mem) { | ||||||
|   return (mem->end_ - mem->start_); |   return (mem->end - mem->start); | ||||||
| } | } | ||||||
|  |  | ||||||
| // Return true if 'size' exceeds the end of the RIFF chunk. | // Return true if 'size' exceeds the end of the RIFF chunk. | ||||||
| static WEBP_INLINE int SizeIsInvalid(const MemBuffer* const mem, size_t size) { | static WEBP_INLINE int SizeIsInvalid(const MemBuffer* const mem, size_t size) { | ||||||
|   return (size > mem->riff_end_ - mem->start_); |   return (size > mem->riff_end - mem->start); | ||||||
| } | } | ||||||
|  |  | ||||||
| static WEBP_INLINE void Skip(MemBuffer* const mem, size_t size) { | static WEBP_INLINE void Skip(MemBuffer* const mem, size_t size) { | ||||||
|   mem->start_ += size; |   mem->start += size; | ||||||
| } | } | ||||||
|  |  | ||||||
| static WEBP_INLINE void Rewind(MemBuffer* const mem, size_t size) { | static WEBP_INLINE void Rewind(MemBuffer* const mem, size_t size) { | ||||||
|   mem->start_ -= size; |   mem->start -= size; | ||||||
| } | } | ||||||
|  |  | ||||||
| static WEBP_INLINE const uint8_t* GetBuffer(MemBuffer* const mem) { | static WEBP_INLINE const uint8_t* GetBuffer(MemBuffer* const mem) { | ||||||
|   return mem->buf_ + mem->start_; |   return mem->buf + mem->start; | ||||||
| } | } | ||||||
|  |  | ||||||
| // Read from 'mem' and skip the read bytes. | // Read from 'mem' and skip the read bytes. | ||||||
| static WEBP_INLINE uint8_t ReadByte(MemBuffer* const mem) { | static WEBP_INLINE uint8_t ReadByte(MemBuffer* const mem) { | ||||||
|   const uint8_t byte = mem->buf_[mem->start_]; |   const uint8_t byte = mem->buf[mem->start]; | ||||||
|   Skip(mem, 1); |   Skip(mem, 1); | ||||||
|   return byte; |   return byte; | ||||||
| } | } | ||||||
|  |  | ||||||
| static WEBP_INLINE int ReadLE16s(MemBuffer* const mem) { | static WEBP_INLINE int ReadLE16s(MemBuffer* const mem) { | ||||||
|   const uint8_t* const data = mem->buf_ + mem->start_; |   const uint8_t* const data = mem->buf + mem->start; | ||||||
|   const int val = GetLE16(data); |   const int val = GetLE16(data); | ||||||
|   Skip(mem, 2); |   Skip(mem, 2); | ||||||
|   return val; |   return val; | ||||||
| } | } | ||||||
|  |  | ||||||
| static WEBP_INLINE int ReadLE24s(MemBuffer* const mem) { | static WEBP_INLINE int ReadLE24s(MemBuffer* const mem) { | ||||||
|   const uint8_t* const data = mem->buf_ + mem->start_; |   const uint8_t* const data = mem->buf + mem->start; | ||||||
|   const int val = GetLE24(data); |   const int val = GetLE24(data); | ||||||
|   Skip(mem, 3); |   Skip(mem, 3); | ||||||
|   return val; |   return val; | ||||||
| } | } | ||||||
|  |  | ||||||
| static WEBP_INLINE uint32_t ReadLE32(MemBuffer* const mem) { | static WEBP_INLINE uint32_t ReadLE32(MemBuffer* const mem) { | ||||||
|   const uint8_t* const data = mem->buf_ + mem->start_; |   const uint8_t* const data = mem->buf + mem->start; | ||||||
|   const uint32_t val = GetLE32(data); |   const uint32_t val = GetLE32(data); | ||||||
|   Skip(mem, 4); |   Skip(mem, 4); | ||||||
|   return val; |   return val; | ||||||
| @@ -175,20 +175,20 @@ static WEBP_INLINE uint32_t ReadLE32(MemBuffer* const mem) { | |||||||
| // Secondary chunk parsing | // Secondary chunk parsing | ||||||
|  |  | ||||||
| static void AddChunk(WebPDemuxer* const dmux, Chunk* const chunk) { | static void AddChunk(WebPDemuxer* const dmux, Chunk* const chunk) { | ||||||
|   *dmux->chunks_tail_ = chunk; |   *dmux->chunks_tail = chunk; | ||||||
|   chunk->next_ = NULL; |   chunk->next = NULL; | ||||||
|   dmux->chunks_tail_ = &chunk->next_; |   dmux->chunks_tail = &chunk->next; | ||||||
| } | } | ||||||
|  |  | ||||||
| // Add a frame to the end of the list, ensuring the last frame is complete. | // Add a frame to the end of the list, ensuring the last frame is complete. | ||||||
| // Returns true on success, false otherwise. | // Returns true on success, false otherwise. | ||||||
| static int AddFrame(WebPDemuxer* const dmux, Frame* const frame) { | static int AddFrame(WebPDemuxer* const dmux, Frame* const frame) { | ||||||
|   const Frame* const last_frame = *dmux->frames_tail_; |   const Frame* const last_frame = *dmux->frames_tail; | ||||||
|   if (last_frame != NULL && !last_frame->complete_) return 0; |   if (last_frame != NULL && !last_frame->complete) return 0; | ||||||
|  |  | ||||||
|   *dmux->frames_tail_ = frame; |   *dmux->frames_tail = frame; | ||||||
|   frame->next_ = NULL; |   frame->next = NULL; | ||||||
|   dmux->frames_tail_ = &frame->next_; |   dmux->frames_tail = &frame->next; | ||||||
|   return 1; |   return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -196,13 +196,13 @@ static void SetFrameInfo(size_t start_offset, size_t size, | |||||||
|                          int frame_num, int complete, |                          int frame_num, int complete, | ||||||
|                          const WebPBitstreamFeatures* const features, |                          const WebPBitstreamFeatures* const features, | ||||||
|                          Frame* const frame) { |                          Frame* const frame) { | ||||||
|   frame->img_components_[0].offset_ = start_offset; |   frame->img_components[0].offset = start_offset; | ||||||
|   frame->img_components_[0].size_ = size; |   frame->img_components[0].size = size; | ||||||
|   frame->width_ = features->width; |   frame->width = features->width; | ||||||
|   frame->height_ = features->height; |   frame->height = features->height; | ||||||
|   frame->has_alpha_ |= features->has_alpha; |   frame->has_alpha |= features->has_alpha; | ||||||
|   frame->frame_num_ = frame_num; |   frame->frame_num = frame_num; | ||||||
|   frame->complete_ = complete; |   frame->complete = complete; | ||||||
| } | } | ||||||
|  |  | ||||||
| // Store image bearing chunks to 'frame'. 'min_size' is an optional size | // Store image bearing chunks to 'frame'. 'min_size' is an optional size | ||||||
| @@ -218,7 +218,7 @@ static ParseStatus StoreFrame(int frame_num, uint32_t min_size, | |||||||
|   if (done) return PARSE_NEED_MORE_DATA; |   if (done) return PARSE_NEED_MORE_DATA; | ||||||
|  |  | ||||||
|   do { |   do { | ||||||
|     const size_t chunk_start_offset = mem->start_; |     const size_t chunk_start_offset = mem->start; | ||||||
|     const uint32_t fourcc = ReadLE32(mem); |     const uint32_t fourcc = ReadLE32(mem); | ||||||
|     const uint32_t payload_size = ReadLE32(mem); |     const uint32_t payload_size = ReadLE32(mem); | ||||||
|     uint32_t payload_size_padded; |     uint32_t payload_size_padded; | ||||||
| @@ -238,10 +238,10 @@ static ParseStatus StoreFrame(int frame_num, uint32_t min_size, | |||||||
|       case MKFOURCC('A', 'L', 'P', 'H'): |       case MKFOURCC('A', 'L', 'P', 'H'): | ||||||
|         if (alpha_chunks == 0) { |         if (alpha_chunks == 0) { | ||||||
|           ++alpha_chunks; |           ++alpha_chunks; | ||||||
|           frame->img_components_[1].offset_ = chunk_start_offset; |           frame->img_components[1].offset = chunk_start_offset; | ||||||
|           frame->img_components_[1].size_ = chunk_size; |           frame->img_components[1].size = chunk_size; | ||||||
|           frame->has_alpha_ = 1; |           frame->has_alpha = 1; | ||||||
|           frame->frame_num_ = frame_num; |           frame->frame_num = frame_num; | ||||||
|           Skip(mem, payload_available); |           Skip(mem, payload_available); | ||||||
|         } else { |         } else { | ||||||
|           goto Done; |           goto Done; | ||||||
| @@ -256,7 +256,7 @@ static ParseStatus StoreFrame(int frame_num, uint32_t min_size, | |||||||
|           // is incomplete. |           // is incomplete. | ||||||
|           WebPBitstreamFeatures features; |           WebPBitstreamFeatures features; | ||||||
|           const VP8StatusCode vp8_status = |           const VP8StatusCode vp8_status = | ||||||
|               WebPGetFeatures(mem->buf_ + chunk_start_offset, chunk_size, |               WebPGetFeatures(mem->buf + chunk_start_offset, chunk_size, | ||||||
|                               &features); |                               &features); | ||||||
|           if (status == PARSE_NEED_MORE_DATA && |           if (status == PARSE_NEED_MORE_DATA && | ||||||
|               vp8_status == VP8_STATUS_NOT_ENOUGH_DATA) { |               vp8_status == VP8_STATUS_NOT_ENOUGH_DATA) { | ||||||
| @@ -281,7 +281,7 @@ static ParseStatus StoreFrame(int frame_num, uint32_t min_size, | |||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (mem->start_ == mem->riff_end_) { |     if (mem->start == mem->riff_end) { | ||||||
|       done = 1; |       done = 1; | ||||||
|     } else if (MemDataSize(mem) < CHUNK_HEADER_SIZE) { |     } else if (MemDataSize(mem) < CHUNK_HEADER_SIZE) { | ||||||
|       status = PARSE_NEED_MORE_DATA; |       status = PARSE_NEED_MORE_DATA; | ||||||
| @@ -310,42 +310,42 @@ static ParseStatus NewFrame(const MemBuffer* const mem, | |||||||
| // 'frame_chunk_size' is the previously validated, padded chunk size. | // 'frame_chunk_size' is the previously validated, padded chunk size. | ||||||
| static ParseStatus ParseAnimationFrame( | static ParseStatus ParseAnimationFrame( | ||||||
|     WebPDemuxer* const dmux, uint32_t frame_chunk_size) { |     WebPDemuxer* const dmux, uint32_t frame_chunk_size) { | ||||||
|   const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG); |   const int is_animation = !!(dmux->feature_flags & ANIMATION_FLAG); | ||||||
|   const uint32_t anmf_payload_size = frame_chunk_size - ANMF_CHUNK_SIZE; |   const uint32_t anmf_payload_size = frame_chunk_size - ANMF_CHUNK_SIZE; | ||||||
|   int added_frame = 0; |   int added_frame = 0; | ||||||
|   int bits; |   int bits; | ||||||
|   MemBuffer* const mem = &dmux->mem_; |   MemBuffer* const mem = &dmux->mem; | ||||||
|   Frame* frame; |   Frame* frame; | ||||||
|   size_t start_offset; |   size_t start_offset; | ||||||
|   ParseStatus status = |   ParseStatus status = | ||||||
|       NewFrame(mem, ANMF_CHUNK_SIZE, frame_chunk_size, &frame); |       NewFrame(mem, ANMF_CHUNK_SIZE, frame_chunk_size, &frame); | ||||||
|   if (status != PARSE_OK) return status; |   if (status != PARSE_OK) return status; | ||||||
|  |  | ||||||
|   frame->x_offset_       = 2 * ReadLE24s(mem); |   frame->x_offset       = 2 * ReadLE24s(mem); | ||||||
|   frame->y_offset_       = 2 * ReadLE24s(mem); |   frame->y_offset       = 2 * ReadLE24s(mem); | ||||||
|   frame->width_          = 1 + ReadLE24s(mem); |   frame->width          = 1 + ReadLE24s(mem); | ||||||
|   frame->height_         = 1 + ReadLE24s(mem); |   frame->height         = 1 + ReadLE24s(mem); | ||||||
|   frame->duration_       = ReadLE24s(mem); |   frame->duration       = ReadLE24s(mem); | ||||||
|   bits = ReadByte(mem); |   bits = ReadByte(mem); | ||||||
|   frame->dispose_method_ = |   frame->dispose_method = | ||||||
|       (bits & 1) ? WEBP_MUX_DISPOSE_BACKGROUND : WEBP_MUX_DISPOSE_NONE; |       (bits & 1) ? WEBP_MUX_DISPOSE_BACKGROUND : WEBP_MUX_DISPOSE_NONE; | ||||||
|   frame->blend_method_ = (bits & 2) ? WEBP_MUX_NO_BLEND : WEBP_MUX_BLEND; |   frame->blend_method = (bits & 2) ? WEBP_MUX_NO_BLEND : WEBP_MUX_BLEND; | ||||||
|   if (frame->width_ * (uint64_t)frame->height_ >= MAX_IMAGE_AREA) { |   if (frame->width * (uint64_t)frame->height >= MAX_IMAGE_AREA) { | ||||||
|     WebPSafeFree(frame); |     WebPSafeFree(frame); | ||||||
|     return PARSE_ERROR; |     return PARSE_ERROR; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Store a frame only if the animation flag is set there is some data for |   // Store a frame only if the animation flag is set there is some data for | ||||||
|   // this frame is available. |   // this frame is available. | ||||||
|   start_offset = mem->start_; |   start_offset = mem->start; | ||||||
|   status = StoreFrame(dmux->num_frames_ + 1, anmf_payload_size, mem, frame); |   status = StoreFrame(dmux->num_frames + 1, anmf_payload_size, mem, frame); | ||||||
|   if (status != PARSE_ERROR && mem->start_ - start_offset > anmf_payload_size) { |   if (status != PARSE_ERROR && mem->start - start_offset > anmf_payload_size) { | ||||||
|     status = PARSE_ERROR; |     status = PARSE_ERROR; | ||||||
|   } |   } | ||||||
|   if (status != PARSE_ERROR && is_animation && frame->frame_num_ > 0) { |   if (status != PARSE_ERROR && is_animation && frame->frame_num > 0) { | ||||||
|     added_frame = AddFrame(dmux, frame); |     added_frame = AddFrame(dmux, frame); | ||||||
|     if (added_frame) { |     if (added_frame) { | ||||||
|       ++dmux->num_frames_; |       ++dmux->num_frames; | ||||||
|     } else { |     } else { | ||||||
|       status = PARSE_ERROR; |       status = PARSE_ERROR; | ||||||
|     } |     } | ||||||
| @@ -364,8 +364,8 @@ static int StoreChunk(WebPDemuxer* const dmux, | |||||||
|   Chunk* const chunk = (Chunk*)WebPSafeCalloc(1ULL, sizeof(*chunk)); |   Chunk* const chunk = (Chunk*)WebPSafeCalloc(1ULL, sizeof(*chunk)); | ||||||
|   if (chunk == NULL) return 0; |   if (chunk == NULL) return 0; | ||||||
|  |  | ||||||
|   chunk->data_.offset_ = start_offset; |   chunk->data.offset = start_offset; | ||||||
|   chunk->data_.size_ = size; |   chunk->data.size = size; | ||||||
|   AddChunk(dmux, chunk); |   AddChunk(dmux, chunk); | ||||||
|   return 1; |   return 1; | ||||||
| } | } | ||||||
| @@ -389,9 +389,9 @@ static ParseStatus ReadHeader(MemBuffer* const mem) { | |||||||
|   if (riff_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; |   if (riff_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; | ||||||
|  |  | ||||||
|   // There's no point in reading past the end of the RIFF chunk |   // There's no point in reading past the end of the RIFF chunk | ||||||
|   mem->riff_end_ = riff_size + CHUNK_HEADER_SIZE; |   mem->riff_end = riff_size + CHUNK_HEADER_SIZE; | ||||||
|   if (mem->buf_size_ > mem->riff_end_) { |   if (mem->buf_size > mem->riff_end) { | ||||||
|     mem->buf_size_ = mem->end_ = mem->riff_end_; |     mem->buf_size = mem->end = mem->riff_end; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Skip(mem, RIFF_HEADER_SIZE); |   Skip(mem, RIFF_HEADER_SIZE); | ||||||
| @@ -400,12 +400,12 @@ static ParseStatus ReadHeader(MemBuffer* const mem) { | |||||||
|  |  | ||||||
| static ParseStatus ParseSingleImage(WebPDemuxer* const dmux) { | static ParseStatus ParseSingleImage(WebPDemuxer* const dmux) { | ||||||
|   const size_t min_size = CHUNK_HEADER_SIZE; |   const size_t min_size = CHUNK_HEADER_SIZE; | ||||||
|   MemBuffer* const mem = &dmux->mem_; |   MemBuffer* const mem = &dmux->mem; | ||||||
|   Frame* frame; |   Frame* frame; | ||||||
|   ParseStatus status; |   ParseStatus status; | ||||||
|   int image_added = 0; |   int image_added = 0; | ||||||
|  |  | ||||||
|   if (dmux->frames_ != NULL) return PARSE_ERROR; |   if (dmux->frames != NULL) return PARSE_ERROR; | ||||||
|   if (SizeIsInvalid(mem, min_size)) return PARSE_ERROR; |   if (SizeIsInvalid(mem, min_size)) return PARSE_ERROR; | ||||||
|   if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA; |   if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA; | ||||||
|  |  | ||||||
| @@ -414,29 +414,29 @@ static ParseStatus ParseSingleImage(WebPDemuxer* const dmux) { | |||||||
|  |  | ||||||
|   // For the single image case we allow parsing of a partial frame, so no |   // For the single image case we allow parsing of a partial frame, so no | ||||||
|   // minimum size is imposed here. |   // minimum size is imposed here. | ||||||
|   status = StoreFrame(1, 0, &dmux->mem_, frame); |   status = StoreFrame(1, 0, &dmux->mem, frame); | ||||||
|   if (status != PARSE_ERROR) { |   if (status != PARSE_ERROR) { | ||||||
|     const int has_alpha = !!(dmux->feature_flags_ & ALPHA_FLAG); |     const int has_alpha = !!(dmux->feature_flags & ALPHA_FLAG); | ||||||
|     // Clear any alpha when the alpha flag is missing. |     // Clear any alpha when the alpha flag is missing. | ||||||
|     if (!has_alpha && frame->img_components_[1].size_ > 0) { |     if (!has_alpha && frame->img_components[1].size > 0) { | ||||||
|       frame->img_components_[1].offset_ = 0; |       frame->img_components[1].offset = 0; | ||||||
|       frame->img_components_[1].size_ = 0; |       frame->img_components[1].size = 0; | ||||||
|       frame->has_alpha_ = 0; |       frame->has_alpha = 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Use the frame width/height as the canvas values for non-vp8x files. |     // Use the frame width/height as the canvas values for non-vp8x files. | ||||||
|     // Also, set ALPHA_FLAG if this is a lossless image with alpha. |     // Also, set ALPHA_FLAG if this is a lossless image with alpha. | ||||||
|     if (!dmux->is_ext_format_ && frame->width_ > 0 && frame->height_ > 0) { |     if (!dmux->is_ext_format && frame->width > 0 && frame->height > 0) { | ||||||
|       dmux->state_ = WEBP_DEMUX_PARSED_HEADER; |       dmux->state = WEBP_DEMUX_PARSED_HEADER; | ||||||
|       dmux->canvas_width_ = frame->width_; |       dmux->canvas_width = frame->width; | ||||||
|       dmux->canvas_height_ = frame->height_; |       dmux->canvas_height = frame->height; | ||||||
|       dmux->feature_flags_ |= frame->has_alpha_ ? ALPHA_FLAG : 0; |       dmux->feature_flags |= frame->has_alpha ? ALPHA_FLAG : 0; | ||||||
|     } |     } | ||||||
|     if (!AddFrame(dmux, frame)) { |     if (!AddFrame(dmux, frame)) { | ||||||
|       status = PARSE_ERROR;  // last frame was left incomplete |       status = PARSE_ERROR;  // last frame was left incomplete | ||||||
|     } else { |     } else { | ||||||
|       image_added = 1; |       image_added = 1; | ||||||
|       dmux->num_frames_ = 1; |       dmux->num_frames = 1; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -445,14 +445,14 @@ static ParseStatus ParseSingleImage(WebPDemuxer* const dmux) { | |||||||
| } | } | ||||||
|  |  | ||||||
| static ParseStatus ParseVP8XChunks(WebPDemuxer* const dmux) { | static ParseStatus ParseVP8XChunks(WebPDemuxer* const dmux) { | ||||||
|   const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG); |   const int is_animation = !!(dmux->feature_flags & ANIMATION_FLAG); | ||||||
|   MemBuffer* const mem = &dmux->mem_; |   MemBuffer* const mem = &dmux->mem; | ||||||
|   int anim_chunks = 0; |   int anim_chunks = 0; | ||||||
|   ParseStatus status = PARSE_OK; |   ParseStatus status = PARSE_OK; | ||||||
|  |  | ||||||
|   do { |   do { | ||||||
|     int store_chunk = 1; |     int store_chunk = 1; | ||||||
|     const size_t chunk_start_offset = mem->start_; |     const size_t chunk_start_offset = mem->start; | ||||||
|     const uint32_t fourcc = ReadLE32(mem); |     const uint32_t fourcc = ReadLE32(mem); | ||||||
|     const uint32_t chunk_size = ReadLE32(mem); |     const uint32_t chunk_size = ReadLE32(mem); | ||||||
|     uint32_t chunk_size_padded; |     uint32_t chunk_size_padded; | ||||||
| @@ -483,8 +483,8 @@ static ParseStatus ParseVP8XChunks(WebPDemuxer* const dmux) { | |||||||
|           status = PARSE_NEED_MORE_DATA; |           status = PARSE_NEED_MORE_DATA; | ||||||
|         } else if (anim_chunks == 0) { |         } else if (anim_chunks == 0) { | ||||||
|           ++anim_chunks; |           ++anim_chunks; | ||||||
|           dmux->bgcolor_ = ReadLE32(mem); |           dmux->bgcolor = ReadLE32(mem); | ||||||
|           dmux->loop_count_ = ReadLE16s(mem); |           dmux->loop_count = ReadLE16s(mem); | ||||||
|           Skip(mem, chunk_size_padded - ANIM_CHUNK_SIZE); |           Skip(mem, chunk_size_padded - ANIM_CHUNK_SIZE); | ||||||
|         } else { |         } else { | ||||||
|           store_chunk = 0; |           store_chunk = 0; | ||||||
| @@ -498,15 +498,15 @@ static ParseStatus ParseVP8XChunks(WebPDemuxer* const dmux) { | |||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|       case MKFOURCC('I', 'C', 'C', 'P'): { |       case MKFOURCC('I', 'C', 'C', 'P'): { | ||||||
|         store_chunk = !!(dmux->feature_flags_ & ICCP_FLAG); |         store_chunk = !!(dmux->feature_flags & ICCP_FLAG); | ||||||
|         goto Skip; |         goto Skip; | ||||||
|       } |       } | ||||||
|       case MKFOURCC('E', 'X', 'I', 'F'): { |       case MKFOURCC('E', 'X', 'I', 'F'): { | ||||||
|         store_chunk = !!(dmux->feature_flags_ & EXIF_FLAG); |         store_chunk = !!(dmux->feature_flags & EXIF_FLAG); | ||||||
|         goto Skip; |         goto Skip; | ||||||
|       } |       } | ||||||
|       case MKFOURCC('X', 'M', 'P', ' '): { |       case MKFOURCC('X', 'M', 'P', ' '): { | ||||||
|         store_chunk = !!(dmux->feature_flags_ & XMP_FLAG); |         store_chunk = !!(dmux->feature_flags & XMP_FLAG); | ||||||
|         goto Skip; |         goto Skip; | ||||||
|       } |       } | ||||||
|  Skip: |  Skip: | ||||||
| @@ -527,7 +527,7 @@ static ParseStatus ParseVP8XChunks(WebPDemuxer* const dmux) { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (mem->start_ == mem->riff_end_) { |     if (mem->start == mem->riff_end) { | ||||||
|       break; |       break; | ||||||
|     } else if (MemDataSize(mem) < CHUNK_HEADER_SIZE) { |     } else if (MemDataSize(mem) < CHUNK_HEADER_SIZE) { | ||||||
|       status = PARSE_NEED_MORE_DATA; |       status = PARSE_NEED_MORE_DATA; | ||||||
| @@ -538,12 +538,12 @@ static ParseStatus ParseVP8XChunks(WebPDemuxer* const dmux) { | |||||||
| } | } | ||||||
|  |  | ||||||
| static ParseStatus ParseVP8X(WebPDemuxer* const dmux) { | static ParseStatus ParseVP8X(WebPDemuxer* const dmux) { | ||||||
|   MemBuffer* const mem = &dmux->mem_; |   MemBuffer* const mem = &dmux->mem; | ||||||
|   uint32_t vp8x_size; |   uint32_t vp8x_size; | ||||||
|  |  | ||||||
|   if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA; |   if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA; | ||||||
|  |  | ||||||
|   dmux->is_ext_format_ = 1; |   dmux->is_ext_format = 1; | ||||||
|   Skip(mem, TAG_SIZE);  // VP8X |   Skip(mem, TAG_SIZE);  // VP8X | ||||||
|   vp8x_size = ReadLE32(mem); |   vp8x_size = ReadLE32(mem); | ||||||
|   if (vp8x_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; |   if (vp8x_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR; | ||||||
| @@ -552,15 +552,15 @@ static ParseStatus ParseVP8X(WebPDemuxer* const dmux) { | |||||||
|   if (SizeIsInvalid(mem, vp8x_size)) return PARSE_ERROR; |   if (SizeIsInvalid(mem, vp8x_size)) return PARSE_ERROR; | ||||||
|   if (MemDataSize(mem) < vp8x_size) return PARSE_NEED_MORE_DATA; |   if (MemDataSize(mem) < vp8x_size) return PARSE_NEED_MORE_DATA; | ||||||
|  |  | ||||||
|   dmux->feature_flags_ = ReadByte(mem); |   dmux->feature_flags = ReadByte(mem); | ||||||
|   Skip(mem, 3);  // Reserved. |   Skip(mem, 3);  // Reserved. | ||||||
|   dmux->canvas_width_  = 1 + ReadLE24s(mem); |   dmux->canvas_width  = 1 + ReadLE24s(mem); | ||||||
|   dmux->canvas_height_ = 1 + ReadLE24s(mem); |   dmux->canvas_height = 1 + ReadLE24s(mem); | ||||||
|   if (dmux->canvas_width_ * (uint64_t)dmux->canvas_height_ >= MAX_IMAGE_AREA) { |   if (dmux->canvas_width * (uint64_t)dmux->canvas_height >= MAX_IMAGE_AREA) { | ||||||
|     return PARSE_ERROR;  // image final dimension is too large |     return PARSE_ERROR;  // image final dimension is too large | ||||||
|   } |   } | ||||||
|   Skip(mem, vp8x_size - VP8X_CHUNK_SIZE);  // skip any trailing data. |   Skip(mem, vp8x_size - VP8X_CHUNK_SIZE);  // skip any trailing data. | ||||||
|   dmux->state_ = WEBP_DEMUX_PARSED_HEADER; |   dmux->state = WEBP_DEMUX_PARSED_HEADER; | ||||||
|  |  | ||||||
|   if (SizeIsInvalid(mem, CHUNK_HEADER_SIZE)) return PARSE_ERROR; |   if (SizeIsInvalid(mem, CHUNK_HEADER_SIZE)) return PARSE_ERROR; | ||||||
|   if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA; |   if (MemDataSize(mem) < CHUNK_HEADER_SIZE) return PARSE_NEED_MORE_DATA; | ||||||
| @@ -572,13 +572,13 @@ static ParseStatus ParseVP8X(WebPDemuxer* const dmux) { | |||||||
| // Format validation | // Format validation | ||||||
|  |  | ||||||
| static int IsValidSimpleFormat(const WebPDemuxer* const dmux) { | static int IsValidSimpleFormat(const WebPDemuxer* const dmux) { | ||||||
|   const Frame* const frame = dmux->frames_; |   const Frame* const frame = dmux->frames; | ||||||
|   if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1; |   if (dmux->state == WEBP_DEMUX_PARSING_HEADER) return 1; | ||||||
|  |  | ||||||
|   if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0; |   if (dmux->canvas_width <= 0 || dmux->canvas_height <= 0) return 0; | ||||||
|   if (dmux->state_ == WEBP_DEMUX_DONE && frame == NULL) return 0; |   if (dmux->state == WEBP_DEMUX_DONE && frame == NULL) return 0; | ||||||
|  |  | ||||||
|   if (frame->width_ <= 0 || frame->height_ <= 0) return 0; |   if (frame->width <= 0 || frame->height <= 0) return 0; | ||||||
|   return 1; |   return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -587,65 +587,65 @@ static int IsValidSimpleFormat(const WebPDemuxer* const dmux) { | |||||||
| static int CheckFrameBounds(const Frame* const frame, int exact, | static int CheckFrameBounds(const Frame* const frame, int exact, | ||||||
|                             int canvas_width, int canvas_height) { |                             int canvas_width, int canvas_height) { | ||||||
|   if (exact) { |   if (exact) { | ||||||
|     if (frame->x_offset_ != 0 || frame->y_offset_ != 0) { |     if (frame->x_offset != 0 || frame->y_offset != 0) { | ||||||
|       return 0; |       return 0; | ||||||
|     } |     } | ||||||
|     if (frame->width_ != canvas_width || frame->height_ != canvas_height) { |     if (frame->width != canvas_width || frame->height != canvas_height) { | ||||||
|       return 0; |       return 0; | ||||||
|     } |     } | ||||||
|   } else { |   } else { | ||||||
|     if (frame->x_offset_ < 0 || frame->y_offset_ < 0) return 0; |     if (frame->x_offset < 0 || frame->y_offset < 0) return 0; | ||||||
|     if (frame->width_ + frame->x_offset_ > canvas_width) return 0; |     if (frame->width + frame->x_offset > canvas_width) return 0; | ||||||
|     if (frame->height_ + frame->y_offset_ > canvas_height) return 0; |     if (frame->height + frame->y_offset > canvas_height) return 0; | ||||||
|   } |   } | ||||||
|   return 1; |   return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int IsValidExtendedFormat(const WebPDemuxer* const dmux) { | static int IsValidExtendedFormat(const WebPDemuxer* const dmux) { | ||||||
|   const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG); |   const int is_animation = !!(dmux->feature_flags & ANIMATION_FLAG); | ||||||
|   const Frame* f = dmux->frames_; |   const Frame* f = dmux->frames; | ||||||
|  |  | ||||||
|   if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1; |   if (dmux->state == WEBP_DEMUX_PARSING_HEADER) return 1; | ||||||
|  |  | ||||||
|   if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0; |   if (dmux->canvas_width <= 0 || dmux->canvas_height <= 0) return 0; | ||||||
|   if (dmux->loop_count_ < 0) return 0; |   if (dmux->loop_count < 0) return 0; | ||||||
|   if (dmux->state_ == WEBP_DEMUX_DONE && dmux->frames_ == NULL) return 0; |   if (dmux->state == WEBP_DEMUX_DONE && dmux->frames == NULL) return 0; | ||||||
|   if (dmux->feature_flags_ & ~ALL_VALID_FLAGS) return 0;  // invalid bitstream |   if (dmux->feature_flags & ~ALL_VALID_FLAGS) return 0;  // invalid bitstream | ||||||
|  |  | ||||||
|   while (f != NULL) { |   while (f != NULL) { | ||||||
|     const int cur_frame_set = f->frame_num_; |     const int cur_frame_set = f->frame_num; | ||||||
|  |  | ||||||
|     // Check frame properties. |     // Check frame properties. | ||||||
|     for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) { |     for (; f != NULL && f->frame_num == cur_frame_set; f = f->next) { | ||||||
|       const ChunkData* const image = f->img_components_; |       const ChunkData* const image = f->img_components; | ||||||
|       const ChunkData* const alpha = f->img_components_ + 1; |       const ChunkData* const alpha = f->img_components + 1; | ||||||
|  |  | ||||||
|       if (!is_animation && f->frame_num_ > 1) return 0; |       if (!is_animation && f->frame_num > 1) return 0; | ||||||
|  |  | ||||||
|       if (f->complete_) { |       if (f->complete) { | ||||||
|         if (alpha->size_ == 0 && image->size_ == 0) return 0; |         if (alpha->size == 0 && image->size == 0) return 0; | ||||||
|         // Ensure alpha precedes image bitstream. |         // Ensure alpha precedes image bitstream. | ||||||
|         if (alpha->size_ > 0 && alpha->offset_ > image->offset_) { |         if (alpha->size > 0 && alpha->offset > image->offset) { | ||||||
|           return 0; |           return 0; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (f->width_ <= 0 || f->height_ <= 0) return 0; |         if (f->width <= 0 || f->height <= 0) return 0; | ||||||
|       } else { |       } else { | ||||||
|         // There shouldn't be a partial frame in a complete file. |         // There shouldn't be a partial frame in a complete file. | ||||||
|         if (dmux->state_ == WEBP_DEMUX_DONE) return 0; |         if (dmux->state == WEBP_DEMUX_DONE) return 0; | ||||||
|  |  | ||||||
|         // Ensure alpha precedes image bitstream. |         // Ensure alpha precedes image bitstream. | ||||||
|         if (alpha->size_ > 0 && image->size_ > 0 && |         if (alpha->size > 0 && image->size > 0 && | ||||||
|             alpha->offset_ > image->offset_) { |             alpha->offset > image->offset) { | ||||||
|           return 0; |           return 0; | ||||||
|         } |         } | ||||||
|         // There shouldn't be any frames after an incomplete one. |         // There shouldn't be any frames after an incomplete one. | ||||||
|         if (f->next_ != NULL) return 0; |         if (f->next != NULL) return 0; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       if (f->width_ > 0 && f->height_ > 0 && |       if (f->width > 0 && f->height > 0 && | ||||||
|           !CheckFrameBounds(f, !is_animation, |           !CheckFrameBounds(f, !is_animation, | ||||||
|                             dmux->canvas_width_, dmux->canvas_height_)) { |                             dmux->canvas_width, dmux->canvas_height)) { | ||||||
|         return 0; |         return 0; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -657,21 +657,21 @@ static int IsValidExtendedFormat(const WebPDemuxer* const dmux) { | |||||||
| // WebPDemuxer object | // WebPDemuxer object | ||||||
|  |  | ||||||
| static void InitDemux(WebPDemuxer* const dmux, const MemBuffer* const mem) { | static void InitDemux(WebPDemuxer* const dmux, const MemBuffer* const mem) { | ||||||
|   dmux->state_ = WEBP_DEMUX_PARSING_HEADER; |   dmux->state = WEBP_DEMUX_PARSING_HEADER; | ||||||
|   dmux->loop_count_ = 1; |   dmux->loop_count = 1; | ||||||
|   dmux->bgcolor_ = 0xFFFFFFFF;  // White background by default. |   dmux->bgcolor = 0xFFFFFFFF;  // White background by default. | ||||||
|   dmux->canvas_width_ = -1; |   dmux->canvas_width = -1; | ||||||
|   dmux->canvas_height_ = -1; |   dmux->canvas_height = -1; | ||||||
|   dmux->frames_tail_ = &dmux->frames_; |   dmux->frames_tail = &dmux->frames; | ||||||
|   dmux->chunks_tail_ = &dmux->chunks_; |   dmux->chunks_tail = &dmux->chunks; | ||||||
|   dmux->mem_ = *mem; |   dmux->mem = *mem; | ||||||
| } | } | ||||||
|  |  | ||||||
| static ParseStatus CreateRawImageDemuxer(MemBuffer* const mem, | static ParseStatus CreateRawImageDemuxer(MemBuffer* const mem, | ||||||
|                                          WebPDemuxer** demuxer) { |                                          WebPDemuxer** demuxer) { | ||||||
|   WebPBitstreamFeatures features; |   WebPBitstreamFeatures features; | ||||||
|   const VP8StatusCode status = |   const VP8StatusCode status = | ||||||
|       WebPGetFeatures(mem->buf_, mem->buf_size_, &features); |       WebPGetFeatures(mem->buf, mem->buf_size, &features); | ||||||
|   *demuxer = NULL; |   *demuxer = NULL; | ||||||
|   if (status != VP8_STATUS_OK) { |   if (status != VP8_STATUS_OK) { | ||||||
|     return (status == VP8_STATUS_NOT_ENOUGH_DATA) ? PARSE_NEED_MORE_DATA |     return (status == VP8_STATUS_NOT_ENOUGH_DATA) ? PARSE_NEED_MORE_DATA | ||||||
| @@ -683,14 +683,14 @@ static ParseStatus CreateRawImageDemuxer(MemBuffer* const mem, | |||||||
|     Frame* const frame = (Frame*)WebPSafeCalloc(1ULL, sizeof(*frame)); |     Frame* const frame = (Frame*)WebPSafeCalloc(1ULL, sizeof(*frame)); | ||||||
|     if (dmux == NULL || frame == NULL) goto Error; |     if (dmux == NULL || frame == NULL) goto Error; | ||||||
|     InitDemux(dmux, mem); |     InitDemux(dmux, mem); | ||||||
|     SetFrameInfo(0, mem->buf_size_, 1 /*frame_num*/, 1 /*complete*/, &features, |     SetFrameInfo(0, mem->buf_size, 1 /*frame_num*/, 1 /*complete*/, &features, | ||||||
|                  frame); |                  frame); | ||||||
|     if (!AddFrame(dmux, frame)) goto Error; |     if (!AddFrame(dmux, frame)) goto Error; | ||||||
|     dmux->state_ = WEBP_DEMUX_DONE; |     dmux->state = WEBP_DEMUX_DONE; | ||||||
|     dmux->canvas_width_ = frame->width_; |     dmux->canvas_width = frame->width; | ||||||
|     dmux->canvas_height_ = frame->height_; |     dmux->canvas_height = frame->height; | ||||||
|     dmux->feature_flags_ |= frame->has_alpha_ ? ALPHA_FLAG : 0; |     dmux->feature_flags |= frame->has_alpha ? ALPHA_FLAG : 0; | ||||||
|     dmux->num_frames_ = 1; |     dmux->num_frames = 1; | ||||||
|     assert(IsValidSimpleFormat(dmux)); |     assert(IsValidSimpleFormat(dmux)); | ||||||
|     *demuxer = dmux; |     *demuxer = dmux; | ||||||
|     return PARSE_OK; |     return PARSE_OK; | ||||||
| @@ -734,7 +734,7 @@ WebPDemuxer* WebPDemuxInternal(const WebPData* data, int allow_partial, | |||||||
|     return NULL; |     return NULL; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   partial = (mem.buf_size_ < mem.riff_end_); |   partial = (mem.buf_size < mem.riff_end); | ||||||
|   if (!allow_partial && partial) return NULL; |   if (!allow_partial && partial) return NULL; | ||||||
|  |  | ||||||
|   dmux = (WebPDemuxer*)WebPSafeCalloc(1ULL, sizeof(*dmux)); |   dmux = (WebPDemuxer*)WebPSafeCalloc(1ULL, sizeof(*dmux)); | ||||||
| @@ -743,16 +743,16 @@ WebPDemuxer* WebPDemuxInternal(const WebPData* data, int allow_partial, | |||||||
|  |  | ||||||
|   status = PARSE_ERROR; |   status = PARSE_ERROR; | ||||||
|   for (parser = kMasterChunks; parser->parse != NULL; ++parser) { |   for (parser = kMasterChunks; parser->parse != NULL; ++parser) { | ||||||
|     if (!memcmp(parser->id, GetBuffer(&dmux->mem_), TAG_SIZE)) { |     if (!memcmp(parser->id, GetBuffer(&dmux->mem), TAG_SIZE)) { | ||||||
|       status = parser->parse(dmux); |       status = parser->parse(dmux); | ||||||
|       if (status == PARSE_OK) dmux->state_ = WEBP_DEMUX_DONE; |       if (status == PARSE_OK) dmux->state = WEBP_DEMUX_DONE; | ||||||
|       if (status == PARSE_NEED_MORE_DATA && !partial) status = PARSE_ERROR; |       if (status == PARSE_NEED_MORE_DATA && !partial) status = PARSE_ERROR; | ||||||
|       if (status != PARSE_ERROR && !parser->valid(dmux)) status = PARSE_ERROR; |       if (status != PARSE_ERROR && !parser->valid(dmux)) status = PARSE_ERROR; | ||||||
|       if (status == PARSE_ERROR) dmux->state_ = WEBP_DEMUX_PARSE_ERROR; |       if (status == PARSE_ERROR) dmux->state = WEBP_DEMUX_PARSE_ERROR; | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   if (state != NULL) *state = dmux->state_; |   if (state != NULL) *state = dmux->state; | ||||||
|  |  | ||||||
|   if (status == PARSE_ERROR) { |   if (status == PARSE_ERROR) { | ||||||
|     WebPDemuxDelete(dmux); |     WebPDemuxDelete(dmux); | ||||||
| @@ -766,14 +766,14 @@ void WebPDemuxDelete(WebPDemuxer* dmux) { | |||||||
|   Frame* f; |   Frame* f; | ||||||
|   if (dmux == NULL) return; |   if (dmux == NULL) return; | ||||||
|  |  | ||||||
|   for (f = dmux->frames_; f != NULL;) { |   for (f = dmux->frames; f != NULL;) { | ||||||
|     Frame* const cur_frame = f; |     Frame* const cur_frame = f; | ||||||
|     f = f->next_; |     f = f->next; | ||||||
|     WebPSafeFree(cur_frame); |     WebPSafeFree(cur_frame); | ||||||
|   } |   } | ||||||
|   for (c = dmux->chunks_; c != NULL;) { |   for (c = dmux->chunks; c != NULL;) { | ||||||
|     Chunk* const cur_chunk = c; |     Chunk* const cur_chunk = c; | ||||||
|     c = c->next_; |     c = c->next; | ||||||
|     WebPSafeFree(cur_chunk); |     WebPSafeFree(cur_chunk); | ||||||
|   } |   } | ||||||
|   WebPSafeFree(dmux); |   WebPSafeFree(dmux); | ||||||
| @@ -785,12 +785,12 @@ uint32_t WebPDemuxGetI(const WebPDemuxer* dmux, WebPFormatFeature feature) { | |||||||
|   if (dmux == NULL) return 0; |   if (dmux == NULL) return 0; | ||||||
|  |  | ||||||
|   switch (feature) { |   switch (feature) { | ||||||
|     case WEBP_FF_FORMAT_FLAGS:     return dmux->feature_flags_; |     case WEBP_FF_FORMAT_FLAGS:     return dmux->feature_flags; | ||||||
|     case WEBP_FF_CANVAS_WIDTH:     return (uint32_t)dmux->canvas_width_; |     case WEBP_FF_CANVAS_WIDTH:     return (uint32_t)dmux->canvas_width; | ||||||
|     case WEBP_FF_CANVAS_HEIGHT:    return (uint32_t)dmux->canvas_height_; |     case WEBP_FF_CANVAS_HEIGHT:    return (uint32_t)dmux->canvas_height; | ||||||
|     case WEBP_FF_LOOP_COUNT:       return (uint32_t)dmux->loop_count_; |     case WEBP_FF_LOOP_COUNT:       return (uint32_t)dmux->loop_count; | ||||||
|     case WEBP_FF_BACKGROUND_COLOR: return dmux->bgcolor_; |     case WEBP_FF_BACKGROUND_COLOR: return dmux->bgcolor; | ||||||
|     case WEBP_FF_FRAME_COUNT:      return (uint32_t)dmux->num_frames_; |     case WEBP_FF_FRAME_COUNT:      return (uint32_t)dmux->num_frames; | ||||||
|   } |   } | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
| @@ -800,8 +800,8 @@ uint32_t WebPDemuxGetI(const WebPDemuxer* dmux, WebPFormatFeature feature) { | |||||||
|  |  | ||||||
| static const Frame* GetFrame(const WebPDemuxer* const dmux, int frame_num) { | static const Frame* GetFrame(const WebPDemuxer* const dmux, int frame_num) { | ||||||
|   const Frame* f; |   const Frame* f; | ||||||
|   for (f = dmux->frames_; f != NULL; f = f->next_) { |   for (f = dmux->frames; f != NULL; f = f->next) { | ||||||
|     if (frame_num == f->frame_num_) break; |     if (frame_num == f->frame_num) break; | ||||||
|   } |   } | ||||||
|   return f; |   return f; | ||||||
| } | } | ||||||
| @@ -811,19 +811,19 @@ static const uint8_t* GetFramePayload(const uint8_t* const mem_buf, | |||||||
|                                       size_t* const data_size) { |                                       size_t* const data_size) { | ||||||
|   *data_size = 0; |   *data_size = 0; | ||||||
|   if (frame != NULL) { |   if (frame != NULL) { | ||||||
|     const ChunkData* const image = frame->img_components_; |     const ChunkData* const image = frame->img_components; | ||||||
|     const ChunkData* const alpha = frame->img_components_ + 1; |     const ChunkData* const alpha = frame->img_components + 1; | ||||||
|     size_t start_offset = image->offset_; |     size_t start_offset = image->offset; | ||||||
|     *data_size = image->size_; |     *data_size = image->size; | ||||||
|  |  | ||||||
|     // if alpha exists it precedes image, update the size allowing for |     // if alpha exists it precedes image, update the size allowing for | ||||||
|     // intervening chunks. |     // intervening chunks. | ||||||
|     if (alpha->size_ > 0) { |     if (alpha->size > 0) { | ||||||
|       const size_t inter_size = (image->offset_ > 0) |       const size_t inter_size = (image->offset > 0) | ||||||
|                               ? image->offset_ - (alpha->offset_ + alpha->size_) |                               ? image->offset - (alpha->offset + alpha->size) | ||||||
|                               : 0; |                               : 0; | ||||||
|       start_offset = alpha->offset_; |       start_offset = alpha->offset; | ||||||
|       *data_size  += alpha->size_ + inter_size; |       *data_size  += alpha->size + inter_size; | ||||||
|     } |     } | ||||||
|     return mem_buf + start_offset; |     return mem_buf + start_offset; | ||||||
|   } |   } | ||||||
| @@ -834,23 +834,23 @@ static const uint8_t* GetFramePayload(const uint8_t* const mem_buf, | |||||||
| static int SynthesizeFrame(const WebPDemuxer* const dmux, | static int SynthesizeFrame(const WebPDemuxer* const dmux, | ||||||
|                            const Frame* const frame, |                            const Frame* const frame, | ||||||
|                            WebPIterator* const iter) { |                            WebPIterator* const iter) { | ||||||
|   const uint8_t* const mem_buf = dmux->mem_.buf_; |   const uint8_t* const mem_buf = dmux->mem.buf; | ||||||
|   size_t payload_size = 0; |   size_t payload_size = 0; | ||||||
|   const uint8_t* const payload = GetFramePayload(mem_buf, frame, &payload_size); |   const uint8_t* const payload = GetFramePayload(mem_buf, frame, &payload_size); | ||||||
|   if (payload == NULL) return 0; |   if (payload == NULL) return 0; | ||||||
|   assert(frame != NULL); |   assert(frame != NULL); | ||||||
|  |  | ||||||
|   iter->frame_num      = frame->frame_num_; |   iter->frame_num      = frame->frame_num; | ||||||
|   iter->num_frames     = dmux->num_frames_; |   iter->num_frames     = dmux->num_frames; | ||||||
|   iter->x_offset       = frame->x_offset_; |   iter->x_offset       = frame->x_offset; | ||||||
|   iter->y_offset       = frame->y_offset_; |   iter->y_offset       = frame->y_offset; | ||||||
|   iter->width          = frame->width_; |   iter->width          = frame->width; | ||||||
|   iter->height         = frame->height_; |   iter->height         = frame->height; | ||||||
|   iter->has_alpha      = frame->has_alpha_; |   iter->has_alpha      = frame->has_alpha; | ||||||
|   iter->duration       = frame->duration_; |   iter->duration       = frame->duration; | ||||||
|   iter->dispose_method = frame->dispose_method_; |   iter->dispose_method = frame->dispose_method; | ||||||
|   iter->blend_method   = frame->blend_method_; |   iter->blend_method   = frame->blend_method; | ||||||
|   iter->complete       = frame->complete_; |   iter->complete       = frame->complete; | ||||||
|   iter->fragment.bytes = payload; |   iter->fragment.bytes = payload; | ||||||
|   iter->fragment.size  = payload_size; |   iter->fragment.size  = payload_size; | ||||||
|   return 1; |   return 1; | ||||||
| @@ -860,8 +860,8 @@ static int SetFrame(int frame_num, WebPIterator* const iter) { | |||||||
|   const Frame* frame; |   const Frame* frame; | ||||||
|   const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_; |   const WebPDemuxer* const dmux = (WebPDemuxer*)iter->private_; | ||||||
|   if (dmux == NULL || frame_num < 0) return 0; |   if (dmux == NULL || frame_num < 0) return 0; | ||||||
|   if (frame_num > dmux->num_frames_) return 0; |   if (frame_num > dmux->num_frames) return 0; | ||||||
|   if (frame_num == 0) frame_num = dmux->num_frames_; |   if (frame_num == 0) frame_num = dmux->num_frames; | ||||||
|  |  | ||||||
|   frame = GetFrame(dmux, frame_num); |   frame = GetFrame(dmux, frame_num); | ||||||
|   if (frame == NULL) return 0; |   if (frame == NULL) return 0; | ||||||
| @@ -896,11 +896,11 @@ void WebPDemuxReleaseIterator(WebPIterator* iter) { | |||||||
| // Chunk iteration | // Chunk iteration | ||||||
|  |  | ||||||
| static int ChunkCount(const WebPDemuxer* const dmux, const char fourcc[4]) { | static int ChunkCount(const WebPDemuxer* const dmux, const char fourcc[4]) { | ||||||
|   const uint8_t* const mem_buf = dmux->mem_.buf_; |   const uint8_t* const mem_buf = dmux->mem.buf; | ||||||
|   const Chunk* c; |   const Chunk* c; | ||||||
|   int count = 0; |   int count = 0; | ||||||
|   for (c = dmux->chunks_; c != NULL; c = c->next_) { |   for (c = dmux->chunks; c != NULL; c = c->next) { | ||||||
|     const uint8_t* const header = mem_buf + c->data_.offset_; |     const uint8_t* const header = mem_buf + c->data.offset; | ||||||
|     if (!memcmp(header, fourcc, TAG_SIZE)) ++count; |     if (!memcmp(header, fourcc, TAG_SIZE)) ++count; | ||||||
|   } |   } | ||||||
|   return count; |   return count; | ||||||
| @@ -908,11 +908,11 @@ static int ChunkCount(const WebPDemuxer* const dmux, const char fourcc[4]) { | |||||||
|  |  | ||||||
| static const Chunk* GetChunk(const WebPDemuxer* const dmux, | static const Chunk* GetChunk(const WebPDemuxer* const dmux, | ||||||
|                              const char fourcc[4], int chunk_num) { |                              const char fourcc[4], int chunk_num) { | ||||||
|   const uint8_t* const mem_buf = dmux->mem_.buf_; |   const uint8_t* const mem_buf = dmux->mem.buf; | ||||||
|   const Chunk* c; |   const Chunk* c; | ||||||
|   int count = 0; |   int count = 0; | ||||||
|   for (c = dmux->chunks_; c != NULL; c = c->next_) { |   for (c = dmux->chunks; c != NULL; c = c->next) { | ||||||
|     const uint8_t* const header = mem_buf + c->data_.offset_; |     const uint8_t* const header = mem_buf + c->data.offset; | ||||||
|     if (!memcmp(header, fourcc, TAG_SIZE)) ++count; |     if (!memcmp(header, fourcc, TAG_SIZE)) ++count; | ||||||
|     if (count == chunk_num) break; |     if (count == chunk_num) break; | ||||||
|   } |   } | ||||||
| @@ -930,10 +930,10 @@ static int SetChunk(const char fourcc[4], int chunk_num, | |||||||
|   if (chunk_num == 0) chunk_num = count; |   if (chunk_num == 0) chunk_num = count; | ||||||
|  |  | ||||||
|   if (chunk_num <= count) { |   if (chunk_num <= count) { | ||||||
|     const uint8_t* const mem_buf = dmux->mem_.buf_; |     const uint8_t* const mem_buf = dmux->mem.buf; | ||||||
|     const Chunk* const chunk = GetChunk(dmux, fourcc, chunk_num); |     const Chunk* const chunk = GetChunk(dmux, fourcc, chunk_num); | ||||||
|     iter->chunk.bytes = mem_buf + chunk->data_.offset_ + CHUNK_HEADER_SIZE; |     iter->chunk.bytes = mem_buf + chunk->data.offset + CHUNK_HEADER_SIZE; | ||||||
|     iter->chunk.size  = chunk->data_.size_ - CHUNK_HEADER_SIZE; |     iter->chunk.size  = chunk->data.size - CHUNK_HEADER_SIZE; | ||||||
|     iter->num_chunks  = count; |     iter->num_chunks  = count; | ||||||
|     iter->chunk_num   = chunk_num; |     iter->chunk_num   = chunk_num; | ||||||
|     return 1; |     return 1; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user