# SPDX-License-Identifier: GPL-2.0-or-later # # Copyright (C) 2026 Frédéric Tronel import logging import re from math import ceil, log from os import write from typing import IO from io import BytesIO from typeguard import typechecked @typechecked def dump_ppm(pictures: bytes, prefix: str, temporaries: list[IO[bytes]]) -> None: """ Dump PPM pictures from a bytes buffer to files. This function takes a bytes buffer containing PPM pictures, a prefix for the output file names, and a list of temporary files. It extracts each PPM picture from the buffer, checks its validity, and writes it to a file. The output files are named according to the prefix and a zero-padded three-digit number. Args: pictures (bytes): The bytes buffer containing the PPM pictures. prefix (str): The prefix for the output file names. temporaries (list[IO[bytes]]): A list of temporary files that will be used to store the output files. Returns: None Raises: None, but logs errors if: - the PPM picture is not valid (e.g. wrong magic number, dimensions, or color encoding) - an I/O error occurs while creating or writing to an output file """ logger = logging.getLogger(__name__) # "P6\nWIDTH HEIGHT\n255\n" pos = 0 picture = 0 logger.debug('Dumping %d pictures: %s', len(pictures),prefix) while pos[0-9]+) (?P[0-9]+)\n$') m = pattern.match(dimensions) if m is not None: width = int(m['width']) height = int(m['height']) else: logger.error('Impossible to parse dimensions of picture') return else: logger.error('Not a PPM picture') return if max_value != 255: logger.error('Not a valid PPM picture. Color are not encoded on byte. Max value: %d', max_value) header_len=2+1+ceil(log(width, 10))+1+ceil(log(height, 10))+1+3+1 try: with open(filename, 'wb') as out: temporaries.append(out) outfd = out.fileno() length=header_len+3*width*height nb_bytes = 0 while nb_bytes < length: nb_bytes+=write(outfd, pictures[pos+nb_bytes:pos+length]) pos+=length picture+=1 except OSError: logger.error('Impossible to create file: %s', filename)