<commit_before># a simple script to trim MNGs without recompression

import struct
import sys

PNGSIG = "\x89PNG\x0d\x0a\x1a\x0a"
MNGSIG = "\x8AMNG\x0d\x0a\x1a\x0a"


def ReadNG(fn):
    with open(fn, "rb") as f:
        r = f.read()

    chunks = []
    cursor = 0
    sig = r[cursor:cursor + 8]
    cursor += 8
    if sig not in [PNGSIG, MNGSIG]:
        print "wrong sig"
        sys.exit()
    while cursor < len(r):
        offset = cursor
        size = struct.unpack(">I", r[cursor:cursor + 4])[0]
        cursor += 4
        type_ = r[cursor: cursor + 4]
        cursor += 4
        datacrc = r[cursor: cursor + size + 4]
        cursor += size + 4
        if type_ in ["tEXt"]:
            continue
        chunks += [[offset, datacrc, type_]]
    return chunks


def parseMHDR(c):
    assert c[2] == "MHDR"
    x, y, ticks = struct.unpack(">III", c[1][:4 * 3])
    return x, y, ticks


def WriteChunk(t, c):
    t.write(struct.pack(">I", len(c[1]) - 4))
    t.write(c[2])
    t.write(c[1])


def WritePNGFrame(i):
    with open("%s%03i.png" % (fnt, i), "wb") as t:
        t.write(PNGSIG)
        for ii in xrange(3):
            WriteChunk(t, chunks[i * 3 + 1 + ii])


def WriteTruncatedMNG(i, fn): # skip i frames
    # need to skip (i / ticks) seconds
    with open(fn, "wb") as t:
        t.write(MNGSIG)
        WriteChunk(t, chunks[0])
        for c in chunks[1 + i * 3:]:
            WriteChunk(t, c)


fn = sys.argv[1]
fnt = fn.replace(".mng", "")

chunks = ReadNG(fn)

x, y, ticks = parseMHDR(chunks[0])
print "MNG %i x %i, %i f/s" % (x, y, ticks),
print "(%i frames)" % ((len(chunks) - 2) / 3) # 1 MHDR, 1 MEND, then IHDR/IDAT/IEND sequences

#for i in xrange(40):
#    WritePNGFrame(i)
#
#WriteTruncatedMNG(38, "test.mng")<commit_msg>WAV trimming Mame MNGwrite+wavwrite support<commit_after># a simple script to trim MNGs and corresponding WAVs without recompression

# <NAME>, BSD Licence 2013

# only MHRD-(IHDR/[PLTE/]IDAT/IEND)*-MEND are supported
# tEXt and FRAM are dropped
# complex framerate via FRAM not supported

# 1- run to get xxx frames
# 2- enter your first wanted frame's number as the 'skip' one
# 3- rerun to trim

DUMP_START = 500
DUMP_RANGE = 500
SKIP = 676

FRAMES_PER_PNG = 3 # FRAM chunks are ignored, PLTE are not expected

import struct
import sys
import wave

PNGSIG = "\x89PNG\x0d\x0a\x1a\x0a"
MNGSIG = "\x8AMNG\x0d\x0a\x1a\x0a"

def ReadNG(fn):
    with open(fn, "rb") as f:
        r = f.read()

    chunks = []
    cursor = 0
    sig = r[cursor:cursor + 8]
    cursor += 8
    if sig not in [PNGSIG, MNGSIG]:
        print "wrong sig"
        sys.exit()
    while cursor < len(r):
        offset = cursor
        size = struct.unpack(">I", r[cursor:cursor + 4])[0]
        cursor += 4
        type_ = r[cursor: cursor + 4]
        cursor += 4
        datacrc = r[cursor: cursor + size + 4]
        cursor += size + 4
        if type_ in ["tEXt", "FRAM"]:
            continue
        chunks += [[offset, datacrc, type_]] # ugly, lazy :p
    return chunks


def WriteChunk(t, c):
    t.write(struct.pack(">I", len(c[1]) - 4))
    t.write(c[2])
    t.write(c[1])


def parseMHDR(c):
    assert c[2] == "MHDR"
    x, y, ticks = struct.unpack(">III", c[1][:4 * 3])
    return x, y, ticks


def WritePNGFrame(i):
    with open("%s%08i.png" % (fnt, i), "wb") as t:
        t.write(PNGSIG)
        for ii in xrange(FRAMES_PER_PNG):
            WriteChunk(t, chunks[i * FRAMES_PER_PNG + 1 + ii])


def TrimMNG(fn, frames): # skip i frames
    with open("trimmed-%s.mng" % fn, "wb") as t:
        t.write(MNGSIG)
        WriteChunk(t, chunks[0])
        for c in chunks[1 + frames * FRAMES_PER_PNG:]:
            WriteChunk(t, c)


def TrimWav(fn, frames, fps):
    s = wave.open("%s.wav" % fn, 'r')

    framerate = s.getframerate()
    skip = frames * framerate / fps

    total = s.getnframes()
    s.setpos(skip)
    d = s.readframes(total - skip)

    t = wave.open("trimmed-%s.wav" % fn, 'w')
    t.setparams(s.getparams())
    t.writeframes(d)

    t.close()
    s.close()


fn = sys.argv[1]
fnt = fn.replace(".mng", "")

chunks = ReadNG(fn)

x, y, ticks = parseMHDR(chunks[0]) # ticks will be not enough if FRAM chunks are used

print "MNG %i x %i, %i f/s" % (x, y, ticks),
print "(%i frames)" % ((len(chunks) - 2) / FRAMES_PER_PNG) # 1 MHDR + 1 MEND to be skipped

# dump PNG frames
#for i in xrange(DUMP_RANGE):
#    WritePNGFrame(DUMP_START + i)

#trim MNG and WAV
TrimMNG(fnt, SKIP)
TrimWav(fnt, SKIP, ticks)
{'fraction_non_alphanumeric': 0.15531151949798297, 'fraction_numerical': 0.023083818915284625, 'mean_word_length': 2.5031397174254315, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '774362', 'n_tokens_mistral': 1877, 'n_tokens_neox': 1770, 'n_words': 492}