zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

ani.zig (1748B) - Raw


      1 //! https://en.wikipedia.org/wiki/Resource_Interchange_File_Format
      2 //! https://www.moon-soft.com/program/format/windows/ani.htm
      3 //! https://www.gdgsoft.com/anituner/help/aniformat.htm
      4 //! https://www.lomont.org/software/aniexploit/ExploitANI.pdf
      5 //!
      6 //! RIFF( 'ACON'
      7 //!   [LIST( 'INFO' <info_data> )]
      8 //!   [<DISP_ck>]
      9 //!   anih( <ani_header> )
     10 //!   [rate( <rate_info> )]
     11 //!   ['seq '( <sequence_info> )]
     12 //!   LIST( 'fram' icon( <icon_file> ) ... )
     13 //! )
     14 
     15 const std = @import("std");
     16 
     17 const AF_ICON: u32 = 1;
     18 
     19 pub fn isAnimatedIcon(reader: anytype) bool {
     20     const flags = getAniheaderFlags(reader) catch return false;
     21     return flags & AF_ICON == AF_ICON;
     22 }
     23 
     24 fn getAniheaderFlags(reader: anytype) !u32 {
     25     const riff_header = try reader.readBytesNoEof(4);
     26     if (!std.mem.eql(u8, &riff_header, "RIFF")) return error.InvalidFormat;
     27 
     28     _ = try reader.readInt(u32, .little); // size of RIFF chunk
     29 
     30     const form_type = try reader.readBytesNoEof(4);
     31     if (!std.mem.eql(u8, &form_type, "ACON")) return error.InvalidFormat;
     32 
     33     while (true) {
     34         const chunk_id = try reader.readBytesNoEof(4);
     35         const chunk_len = try reader.readInt(u32, .little);
     36         if (!std.mem.eql(u8, &chunk_id, "anih")) {
     37             // TODO: Move file cursor instead of skipBytes
     38             try reader.skipBytes(chunk_len, .{});
     39             continue;
     40         }
     41 
     42         const aniheader = try reader.readStruct(ANIHEADER);
     43         return std.mem.nativeToLittle(u32, aniheader.flags);
     44     }
     45 }
     46 
     47 /// From Microsoft Multimedia Data Standards Update April 15, 1994
     48 const ANIHEADER = extern struct {
     49     cbSizeof: u32,
     50     cFrames: u32,
     51     cSteps: u32,
     52     cx: u32,
     53     cy: u32,
     54     cBitCount: u32,
     55     cPlanes: u32,
     56     jifRate: u32,
     57     flags: u32,
     58 };