1 // Copyright 2024 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 use std::env;
16 use std::process::Command;
17
18 use crabby_avif::decoder::*;
19
main()20 fn main() {
21 // let data: [u8; 32] = [
22 // 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x61, 0x76, 0x69, 0x66, 0x00, 0x00, 0x00,
23 // 0x00, 0x61, 0x76, 0x69, 0x66, 0x6d, 0x69, 0x66, 0x31, 0x6d, 0x69, 0x61, 0x66, 0x4d, 0x41,
24 // 0x31, 0x41,
25 // ];
26 // let data: [u8; 32] = [
27 // 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x61, 0x76, 0x69, 0x67, 0x00, 0x00, 0x00,
28 // 0x00, 0x61, 0x76, 0x69, 0x68, 0x6d, 0x69, 0x66, 0x31, 0x6d, 0x69, 0x61, 0x66, 0x4d, 0x41,
29 // 0x31, 0x41,
30 // ];
31 // let val = Decoder::peek_compatible_file_type(&data);
32 // println!("val: {val}");
33 // return;
34
35 let args: Vec<String> = env::args().collect();
36
37 if args.len() < 3 {
38 println!("Usage: {} <input_avif> <output> [--no-png]", args[0]);
39 std::process::exit(1);
40 }
41 let image_count;
42 {
43 let settings = Settings {
44 strictness: Strictness::None,
45 image_content_to_decode: ImageContentType::All,
46 allow_progressive: true,
47 ..Settings::default()
48 };
49 let mut decoder: Decoder = Default::default();
50 decoder.settings = settings;
51 match decoder.set_io_file(&args[1]) {
52 Ok(_) => {}
53 Err(err) => {
54 println!("failed to set file io: {:#?}", err);
55 std::process::exit(1);
56 }
57 };
58 let res = decoder.parse();
59 if res.is_err() {
60 println!("parse failed! {:#?}", res);
61 std::process::exit(1);
62 }
63 let _image = decoder.image();
64
65 println!("\n^^^ decoder public properties ^^^");
66 println!("image_count: {}", decoder.image_count());
67 println!("timescale: {}", decoder.timescale());
68 println!(
69 "duration_in_timescales: {}",
70 decoder.duration_in_timescales()
71 );
72 println!("duration: {}", decoder.duration());
73 println!("repetition_count: {:#?}", decoder.repetition_count());
74 println!("$$$ end decoder public properties $$$\n");
75
76 image_count = decoder.image_count();
77 //image_count = 1;
78 let mut writer: crabby_avif::utils::y4m::Y4MWriter = Default::default();
79 //let mut writer: crabby_avif::utils::raw::RawWriter = Default::default();
80 writer.filename = Some(args[2].clone());
81 //writer.rgb = true;
82
83 for _i in 0..image_count {
84 let res = decoder.nth_image(0);
85 if res.is_err() {
86 println!("next_image failed! {:#?}", res);
87 std::process::exit(1);
88 }
89 let image = decoder.image().expect("image was none");
90 let ret = writer.write_frame(image);
91 if !ret {
92 println!("error writing y4m file");
93 std::process::exit(1);
94 }
95 println!("timing: {:#?}", decoder.image_timing());
96 }
97 println!("wrote {} frames into {}", image_count, args[2]);
98 }
99 if args.len() == 3 {
100 if image_count <= 1 {
101 let ffmpeg_infile = args[2].to_string();
102 let ffmpeg_outfile = format!("{}.png", args[2]);
103 let ffmpeg = Command::new("ffmpeg")
104 .arg("-i")
105 .arg(ffmpeg_infile)
106 .arg("-frames:v")
107 .arg("1")
108 .arg("-y")
109 .arg(ffmpeg_outfile)
110 .output()
111 .unwrap();
112 if !ffmpeg.status.success() {
113 println!("ffmpeg to convert to png failed");
114 std::process::exit(1);
115 }
116 println!("wrote {}.png", args[2]);
117 } else {
118 let ffmpeg_infile = args[2].to_string();
119 let ffmpeg_outfile = format!("{}.gif", args[2]);
120 let ffmpeg = Command::new("ffmpeg")
121 .arg("-i")
122 .arg(ffmpeg_infile)
123 .arg("-y")
124 .arg(ffmpeg_outfile)
125 .output()
126 .unwrap();
127 if !ffmpeg.status.success() {
128 println!("ffmpeg to convert to gif failed");
129 std::process::exit(1);
130 }
131 println!("wrote {}.gif", args[2]);
132 }
133 }
134 std::process::exit(0);
135 }
136