From e1d688da6e5e16e3e75836ceb0b6fd3235afe6f7 Mon Sep 17 00:00:00 2001 From: yair-mantis Date: Tue, 26 Dec 2023 16:35:32 +0200 Subject: [PATCH] clean and comment --- decode.py | 63 ++++++++++++++++++------------------------------------- 1 file changed, 20 insertions(+), 43 deletions(-) diff --git a/decode.py b/decode.py index e1c88ec..0017289 100644 --- a/decode.py +++ b/decode.py @@ -1,5 +1,3 @@ -# coding: utf-8 - from os import system import numpy as np from tqdm import tqdm @@ -7,30 +5,34 @@ import pandas as pd import pcapng from struct import unpack from PIL import Image -import cv2 - - -pd.options.display.max_colwidth = 150 +# Read packets from a pcap file scanner = pcapng.scanner.FileScanner(open('in.pcap', 'rb')) blocks = list(tqdm(scanner)) +# Helper function to safely get an attribute from an object def tryget(obj, att): if hasattr(obj, att): return getattr(obj, att) return None +# Create a DataFrame with packet lengths df = pd.DataFrame([{'index': i, 'length': tryget(obj, 'packet_len')} for i, obj in enumerate(blocks)]) -# get udp packets + + +# Filter and extract data packets of a specific length data = [blocks[i] for i in df[df.length == 6972.0].index] -# remove udp header + +# Remove the UDP header from the packets raw = [d.packet_data[0x2a:] for d in data] +# Function to parse packet data def parse(data): - hdr = 4 + 2 * 7 + hdr = 4 + 2 * 7 # Header length + # Unpack data into variables c1, c2, part, a, ffaa, b, c, d = unpack('>Lhhhhhhh', data[:hdr]) ret = locals() del ret['data'] @@ -39,16 +41,17 @@ def parse(data): return ret +# Parse each packet and create a DataFrame df = pd.DataFrame([parse(d) for d in raw]) df2 = df[[c for c in df.columns if c != 'data']] +# Function to group data into frames def getframes(df): frames = [] current = [] for i, row in df.iterrows(): if row.part == 0: - # roll over if len(current) > 0: frames.append(current) current = [] @@ -58,48 +61,22 @@ def getframes(df): return [b''.join(parts) for parts in frames] +# Function to convert binary frame data into images def image16(frame, width, height, pixelformat='>H'): return [ Image.fromarray(np.frombuffer(frame, dtype=pixelformat).reshape(width, height)) for frame in frames if len(frame) == 2 * width * height - ] - - -def showvideo(images): - # wip - videodims = images[0].size - fourcc = cv2.VideoWriter_fourcc(*'avc1') - video = cv2.VideoWriter("test.mp4", fourcc, 60, videodims) - img = Image.new('RGB', videodims, color='darkred') - # draw stuff that goes on every frame here - for i in range(0, 60*60): - imtemp = img.copy() - # draw frame specific stuff here. - video.write(cv2.cvtColor(np.array(imtemp), cv2.COLOR_RGB2BGR)) - video.release() - -# def shape(frames, width, height, mode='RGB'): -# return [Image.frombytes('RGB', (width, height), frame) for frame in frames if len(frame) == width * height * 3] + ] +# Get frames and convert them to images frames = getframes(df) images = image16(frames, 384, 288) + +# Save each image as a PNG file for i, img in enumerate(tqdm(images)): img.save(f'{i:04}.png') -# frame = b''.join(df.iloc[:32]['data']) -# Image.frombytes('RGB', (288, 256), frame).show() -start_len = len(b'T=(-1.665884e-08)*X^4+(1.347094e-05)*X^3+(-4.396264e-03)*X^2+(9.506939e-01)*X+(-6.353247e+01)\r\n') -# 250 bytes at start of frame -equations = {x[:250].decode().strip() for x in df[df.part == 0]['data']} -# seen only a single equation on all packets -assert len(equations) == 1 - -assert list(equations)[0] == 'T=(-1.665884e-08)*X^4+(1.347094e-05)*X^3+(-4.396264e-03)*X^2+(9.506939e-01)*X+(-6.353247e+01)' - -# we have 6372 packets -assert df.shape[0] == 6372 - -# produce a video -system('ffmpeg -f image2 -framerate 25 -i %04d.png -vf "transpose=1" -s 384x288 -vcodec libx264 -pix_fmt yuv420p thermal.mp4') +# Produce a video from the saved images +system('ffmpeg -hide_banner -loglevel info -y -f image2 -framerate 25 -i %04d.png -vf "transpose=1" -s 384x288 -vcodec libx264 -pix_fmt yuv420p thermal.mp4') print('to play: ffplay thermal.mp4')