Coverage for pyguymer3/media/does_FLAC_have_padding.py: 90%
20 statements
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-08 18:47 +0000
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-08 18:47 +0000
1#!/usr/bin/env python3
3# Define function ...
4def does_FLAC_have_padding(
5 fname,
6 /,
7):
8 # NOTE: The following website has some very useful information on how to
9 # parse FLAC files.
10 # * https://xiph.org/flac/format.html
12 # Import standard modules ...
13 import os
15 # List block types ...
16 blocks = {
17 0 : "STREAMINFO",
18 1 : "PADDING",
19 2 : "APPLICATION",
20 3 : "SEEKTABLE",
21 4 : "VORBIS_COMMENT",
22 5 : "CUESHEET",
23 6 : "PICTURE",
24 127 : "INVALID",
25 }
27 # Open FLAC read-only ...
28 with open(fname, "rb") as fObj:
29 # Create short-hand ...
30 fsize = os.path.getsize(fname) # [B]
32 # Read magic marker and raise exception if it is not expected ...
33 if fObj.read(4).decode("utf-8") != "fLaC":
34 raise Exception(f"\"{fname}\" is not a FLAC") from None
36 # Initialize flag ...
37 last = False
39 # Loop over entire contents of FLAC ...
40 while fObj.tell() < fsize:
41 # Attempt to read 1 byte as a big-endian un-signed integer ...
42 name = int.from_bytes(fObj.read(1), byteorder = "big", signed = False)
44 # Check if this integer has the "last block" flag set and take it
45 # off ...
46 if name > 127:
47 last = True
48 name -= 128
50 # Attempt to read 3 bytes as a big-endian un-signed integer ...
51 val = int.from_bytes(fObj.read(3), byteorder = "big", signed = False) # [B]
53 # Check if it is a PADDING block ...
54 if blocks.get(name, "RESERVED") == "PADDING":
55 return True
57 # Check if this is the last block before the frames ...
58 if last:
59 # Stop looping ...
60 break
62 # Skip to the end of the block ...
63 fObj.seek(val, os.SEEK_CUR)
65 # Return answer ...
66 return False