From fb83d36b65c3cdfdd4bf678c11b212096384f3ec Mon Sep 17 00:00:00 2001 From: j <0x006A@0x2620.org> Date: Sun, 2 May 2010 18:25:32 +0200 Subject: [PATCH] move variables into struct, add option to define format --- oxframe.c | 135 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 91 insertions(+), 44 deletions(-) diff --git a/oxframe.c b/oxframe.c index 367fac4..d2f7852 100644 --- a/oxframe.c +++ b/oxframe.c @@ -28,22 +28,21 @@ #include -static const char *output = NULL; +typedef enum { + oxImageNotSet, + oxPNG, + oxJPG, +} oxImageFormat; -long frame_pos = 0, duration = 0; -int image_width = -1, image_height = -1; - -const char *optstring = "h:x:y:p:i:o:"; -struct option options [] = { - {"help",required_argument,NULL,'h'}, - {"width",required_argument,NULL,'x'}, - {"height",required_argument,NULL,'y'}, - {"pos",required_argument,NULL,'p'}, - {"input",required_argument,NULL,'i'}, - {"output",required_argument,NULL,'o'}, - {NULL,0,NULL,0} - -}; +typedef struct _oxstate { + const char *input; + const char *output; + oxImageFormat format; + long frame_pos; + long duration; + int image_width; + int image_height; +} oxstate; static void usage(void){ fprintf(stderr, @@ -60,11 +59,14 @@ static void usage(void){ " -o OUTPUT, --output=OUTPUT\n" " path to save frame to, jpg, png supported\n" " (defaults to png)\n" + " -f FORMAT, --output=FORMAT\n" + " output format, jpg or png\n" + " if not provided detected from output extension\n" ); exit(0); } -void write_png_file(OggPlayRGBChannels *data) { +void write_image_file(OggPlayRGBChannels *data, oxstate * state) { Imlib_Image *frame = NULL, *image = NULL; @@ -72,40 +74,40 @@ void write_png_file(OggPlayRGBChannels *data) { frame = imlib_create_image_using_data(data->rgb_width, data->rgb_height, (unsigned int *)data->ptro); - if (image_width > 0 && image_height < 0) { - image_height = data->rgb_height * image_width / data->rgb_width; + if (state->image_width > 0 && state->image_height < 0) { + state->image_height = data->rgb_height * state->image_width / data->rgb_width; } - if (image_height > 0 && image_width < 0) { - image_width = data->rgb_width * image_height / data->rgb_height; + if (state->image_height > 0 && state->image_width < 0) { + state->image_width = data->rgb_width * state->image_height / data->rgb_height; } - if (image_width > 0) { - image = imlib_create_image(image_width, image_height); + if (state->image_width > 0) { + image = imlib_create_image(state->image_width, state->image_height); imlib_context_set_image(image); imlib_blend_image_onto_image(frame, 0, 0, 0, data->rgb_width, data->rgb_height, 0, 0, - image_width, image_height); + state->image_width, state->image_height); } else { imlib_context_set_image(frame); } - if (strstr(&(output[strlen(output)-4]), ".jpg") == NULL) + if(state->format == oxPNG) imlib_image_set_format("png"); else imlib_image_set_format("jpg"); - imlib_save_image(output); + imlib_save_image(state->output); imlib_free_image_and_decache(); imlib_context_set_image(frame); imlib_free_image_and_decache(); - if (image_width > 0) { + if (state->image_width > 0) { imlib_context_set_image(image); imlib_free_image_and_decache(); } } void write_frame (OggPlay * player, int track_num, - OggPlayVideoData * video_data) { + OggPlayVideoData * video_data, oxstate * state) { OggPlayYUVChannels from; OggPlayRGBChannels to; @@ -128,7 +130,7 @@ void write_frame (OggPlay * player, int track_num, oggplay_yuv2bgra (&from, &to); - write_png_file(&to); + write_image_file(&to, state); free(to.ptro); } @@ -139,6 +141,7 @@ int dump_frame_callback (OggPlay *player, int num_tracks, OggPlayDataHeader ** headers; OggPlayVideoData * video_data; OggPlayDataType type; + oxstate * state = (oxstate *)user; for (i = 0; i < num_tracks; i++) { type = oggplay_callback_info_get_type(track_info[i]); @@ -153,15 +156,14 @@ int dump_frame_callback (OggPlay *player, int num_tracks, break; } long pt = oggplay_callback_info_get_presentation_time(headers[0]); - //printf("time: %ld %ld %ld\n", pt, duration, duration-pt); - if (pt >= frame_pos) { + //printf("time: %ld %ld %ld\n", pt, state->duration, state->duration-pt); + if (pt >= state->frame_pos) { video_data = oggplay_callback_info_get_video_data(headers[0]); - write_frame(player, i, video_data); + write_frame(player, i, video_data, state); exit(0); - } else if (duration-pt < 500) { + } else if (state->duration - pt < 500) { video_data = oggplay_callback_info_get_video_data(headers[0]); - write_frame(player, i, video_data); - + write_frame(player, i, video_data, state); } break; @@ -173,6 +175,16 @@ int dump_frame_callback (OggPlay *player, int num_tracks, return 0; } +void init_state(oxstate *state) { + state->input = NULL; + state->output = NULL; + state->frame_pos = 0; + state->duration = 0; + state->image_width = -1; + state->image_height = -1; + state->format = oxImageNotSet; +} + int main (int argc, char * argv[]) { int c,long_option_index; @@ -183,6 +195,22 @@ int main (int argc, char * argv[]) { int fps_denom = 1; int granuleshift = 6; long max_num, offset; + oxstate state; + + const char *optstring = "h:x:y:p:i:o:f:"; + struct option options [] = { + {"help",required_argument,NULL,'h'}, + {"width",required_argument,NULL,'x'}, + {"height",required_argument,NULL,'y'}, + {"pos",required_argument,NULL,'p'}, + {"input",required_argument,NULL,'i'}, + {"output",required_argument,NULL,'o'}, + {"format",required_argument,NULL,'f'}, + {NULL,0,NULL,0} + + }; + + init_state(&state); while(1) { c=getopt_long(argc, argv, optstring, options, &long_option_index); @@ -194,19 +222,25 @@ int main (int argc, char * argv[]) { usage(); break; case 'x': - image_width = atoi(optarg); + state.image_width = atoi(optarg); break; case 'y': - image_height = atoi(optarg); + state.image_height = atoi(optarg); break; case 'p': - frame_pos = 1000 * atof(optarg); + state.frame_pos = 1000 * atof(optarg); break; case 'i': - reader = oggplay_file_reader_new(optarg); + state.input = optarg; + reader = oggplay_file_reader_new(state.input); break; case 'o': - output = optarg; + state.output = optarg; + case 'f': + if (strstr(optarg, "jpg") == NULL) + state.format = oxPNG; + else + state.format = oxJPG; break; } } @@ -215,8 +249,19 @@ int main (int argc, char * argv[]) { usage(); } + if(state.format == oxImageNotSet) { + if (strstr(&(state.output[strlen(state.output)-4]), ".jpg") == NULL) + state.format = oxPNG; + else + state.format = oxJPG; + } + player = oggplay_open_with_reader(reader); + if (state.input == NULL) { + fprintf (stderr, "please provide input file\n"); + exit (1); + } if (player == NULL) { fprintf (stderr, "could not initialise oggplay with this file\n"); exit (1); @@ -229,21 +274,23 @@ int main (int argc, char * argv[]) { } oggplay_set_track_active(player, i); } - oggplay_set_data_callback(player, dump_frame_callback, NULL); + oggplay_set_data_callback(player, dump_frame_callback, &state); max_num = 1 << granuleshift; offset = (1000 * max_num * fps_denom) / fps_num; - duration = oggplay_get_duration(player); + state.duration = oggplay_get_duration(player); + /* if (frame_pos > duration) { fprintf (stderr, "can not seek to frame later than duration\n"); exit (1); } + */ - if(frame_pos - offset > 0) { - if (oggplay_seek(player, frame_pos - offset) == E_OGGPLAY_CANT_SEEK) { - fprintf (stderr, "failed to seeek to %ld\n", frame_pos); + if(state.frame_pos - offset > 0) { + if (oggplay_seek(player, state.frame_pos - offset) == E_OGGPLAY_CANT_SEEK) { + fprintf (stderr, "failed to seeek to %ld\n", state.frame_pos); exit (1); } }