static void decode_callback(int what) { if (what == 0 && !kParams.done) { int duration = 0; if (kParams.dmux != NULL) { WebPIterator* const curr = &kParams.curr_frame; if (!WebPDemuxNextFrame(curr)) { WebPDemuxReleaseIterator(curr); if (WebPDemuxGetFrame(kParams.dmux, 1, curr)) { --kParams.loop_count; kParams.done = (kParams.loop_count == 0); if (kParams.done) return; ClearPreviousFrame(); } else { kParams.decoding_error = 1; kParams.done = 1; return; } } duration = curr->duration; } if (!Decode()) { kParams.decoding_error = 1; kParams.done = 1; } else { glutPostRedisplay(); glutTimerFunc(duration, decode_callback, what); } } }
static void decode_callback(int what) { if (what == 0 && !kParams.done) { int duration = 0; if (kParams.dmux != NULL) { WebPIterator* const curr = &kParams.curr_frame; if (!WebPDemuxNextFrame(curr)) { WebPDemuxReleaseIterator(curr); if (WebPDemuxGetFrame(kParams.dmux, 1, curr)) { --kParams.loop_count; kParams.done = (kParams.loop_count == 0); if (kParams.done) return; ClearPreviousFrame(); } else { kParams.decoding_error = 1; kParams.done = 1; return; } } duration = curr->duration; // Behavior copied from Chrome, cf: // https://cs.chromium.org/chromium/src/third_party/WebKit/Source/ // platform/graphics/DeferredImageDecoder.cpp? // rcl=b4c33049f096cd283f32be9a58b9a9e768227c26&l=246 if (duration <= 10) duration = 100; } if (!Decode()) { kParams.decoding_error = 1; kParams.done = 1; } else { glutPostRedisplay(); glutTimerFunc(duration, decode_callback, what); } } }
static void HandleKey(unsigned char key, int pos_x, int pos_y) { // Note: rescaling the window or toggling some features during an animation // generates visual artifacts. This is not fixed because refreshing the frame // may require rendering the whole animation from start till current frame. (void)pos_x; (void)pos_y; if (key == 'q' || key == 'Q' || key == 27 /* Esc */) { #ifdef FREEGLUT glutLeaveMainLoop(); #else ClearParams(); exit(0); #endif } else if (key == 'c') { if (kParams.has_color_profile && !kParams.decoding_error) { kParams.use_color_profile = 1 - kParams.use_color_profile; if (kParams.has_animation) { // Restart the completed animation to pickup the color profile change. if (kParams.done && kParams.loop_count == 0) { kParams.loop_count = (int)WebPDemuxGetI(kParams.dmux, WEBP_FF_LOOP_COUNT) + 1; kParams.done = 0; // Start the decode loop immediately. glutTimerFunc(0, decode_callback, 0); } } else { Decode(); glutPostRedisplay(); } } } else if (key == 'b') { kParams.draw_anim_background_color = 1 - kParams.draw_anim_background_color; if (!kParams.has_animation) ClearPreviousFrame(); glutPostRedisplay(); } else if (key == 'i') { kParams.print_info = 1 - kParams.print_info; if (!kParams.has_animation) ClearPreviousFrame(); glutPostRedisplay(); } else if (key == 'd') { kParams.only_deltas = 1 - kParams.only_deltas; glutPostRedisplay(); } }
static void HandleReshape(int width, int height) { // Note: reshape doesn't preserve aspect ratio, and might // be handling larger-than-screen pictures incorrectly. glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); kParams.viewport_width = width; kParams.viewport_height = height; if (!kParams.has_animation) ClearPreviousFrame(); }