// Read animated WebP bitstream 'file_str' into 'AnimatedImage' struct. static int ReadAnimatedWebP(const char filename[], const WebPData* const webp_data, AnimatedImage* const image, int dump_frames, const char dump_folder[]) { int ok = 0; int dump_ok = 1; uint32_t frame_index = 0; int prev_frame_timestamp = 0; WebPAnimDecoder* dec; WebPAnimInfo anim_info; memset(image, 0, sizeof(*image)); dec = WebPAnimDecoderNew(webp_data, NULL); if (dec == NULL) { fprintf(stderr, "Error parsing image: %s\n", filename); goto End; } if (!WebPAnimDecoderGetInfo(dec, &anim_info)) { fprintf(stderr, "Error getting global info about the animation\n"); goto End; } // Animation properties. image->canvas_width = anim_info.canvas_width; image->canvas_height = anim_info.canvas_height; image->loop_count = anim_info.loop_count; image->bgcolor = anim_info.bgcolor; // Allocate frames. if (!AllocateFrames(image, anim_info.frame_count)) return 0; // Decode frames. while (WebPAnimDecoderHasMoreFrames(dec)) { DecodedFrame* curr_frame; uint8_t* curr_rgba; uint8_t* frame_rgba; int timestamp; if (!WebPAnimDecoderGetNext(dec, &frame_rgba, ×tamp)) { fprintf(stderr, "Error decoding frame #%u\n", frame_index); goto End; } assert(frame_index < anim_info.frame_count); curr_frame = &image->frames[frame_index]; curr_rgba = curr_frame->rgba; curr_frame->duration = timestamp - prev_frame_timestamp; curr_frame->is_key_frame = 0; // Unused. memcpy(curr_rgba, frame_rgba, image->canvas_width * kNumChannels * image->canvas_height); // Needed only because we may want to compare with GIF later. CleanupTransparentPixels((uint32_t*)curr_rgba, image->canvas_width, image->canvas_height); if (dump_frames && dump_ok) { dump_ok = DumpFrame(filename, dump_folder, frame_index, curr_rgba, image->canvas_width, image->canvas_height); if (!dump_ok) { // Print error once, but continue decode loop. fprintf(stderr, "Error dumping frames to %s\n", dump_folder); } } ++frame_index; prev_frame_timestamp = timestamp; } ok = dump_ok; End: WebPAnimDecoderDelete(dec); return ok; }
PyObject* _anim_decoder_has_more_frames(PyObject* self, PyObject* args) { WebPAnimDecoderObject* decp = (WebPAnimDecoderObject*)self; return Py_BuildValue("i", WebPAnimDecoderHasMoreFrames(decp->dec)); }