aepのCPPlを削除するツール

aepファイルが無駄にデカくなる一因のアレです。
aepxで書き出してCPPlタグの中を削除して~ってするしかないと思っていましたが、削除ツールを作られている方がいるようでしたので挑戦してみました。
※非公式な方法ですので自己責任でお願いします。


aepファイルのデータ構造

aepデータ構造

ドラッグ&ドロップで変換しているということはバイナリいじってるんだろうということで、とりあえずCPPl部分をざっくり削除してみたら「破損したファイル」……。
なのできちんとデータ構造の把握を。
xml形式のaepxファイルと照らし合わせた結果が上図です。
識別子(4バイト)+データ本体の長さ(4バイト)+データ本体
の構成になっているようです。
RIFXって名前からしてもRIFFと同じような構造になっているのでしょう?
さらにさらに中身が空のまっさらなaepと比較したところ、CPPl部分の削除だけでなく、上図の緑の「データ本体の長さ」の部分を書き換えてやる必要があるようでした。
結果、以下の処理をしてやれば(多分)問題なくファイルを開くことができました。
・「CPPl」から「cpid」の間の部分を削除
・LIST:CPPlの文字列だけは残すので「4」にする
・RIFX:LISTから減らした分を元の値から減算する

pythonコード

import os
import sys
import struct

#ファイルを取得してリネーム
args = sys.argv
filepaths = args[1:]  #ファイルパスを保存

for filepath in filepaths:

	filename = os.path.splitext(filepath)[0]    #拡張子なしのファイルパスを取得
	rename_filepath = filename+'_original.aep'  #リネームするためのファイルパス生成
	os.rename(filepath,rename_filepath) #元のファイルをリネーム

	# 各項目のオフセットとデータ型を定義
	block_def = {
		'RIFX'  : {'offset': 0, 'type': '>4sI4s'},#全体のデータサイズ 後ろの4バイトは何なのかわからない
		'svap'  : {'offset': 12, 'type': '>4sI4s'},
		'head'  : {'offset': 24, 'type': '>4sI20s'},
		'nhed'  : {'offset': 52, 'type': '>4sI32s'},#後ろの12バイト分はxmlの値と一致しないのでよくわからない
		'adfr'  : {'offset': 92, 'type': '>4sI8s'},
		'qtlg'  : {'offset': 108, 'type': '>4sI2s'},
		'acer'  : {'offset': 118, 'type': '>4sI2s'},
		'LIST'  : {'offset': 128, 'type': '>4sI'},#CPPlのデータサイズ
		'CPPl'  : {'offset': 136, 'type': '>4s'},
		'cpid'  : {'offset': 0, 'type': '>4s'},
	}

	with open(rename_filepath,'br') as f:

		data = f.read()

		#実際のデータに合わせてオフセットの書き換え

		block_def['CPPl']['offset'] = data.find(b'CPPl')
		block_def['LIST']['offset'] = block_def['CPPl']['offset'] - 8
		block_def['cpid']['offset'] = data.find(b'cpid')


		h = {}
		for k, v in block_def.items():

			h[k] = struct.unpack_from(v['type'], data, v['offset'])

		spl_list = data[:block_def['LIST']['offset']]	#LISTで分割

		spl_svap = spl_list[block_def['svap']['offset']:]	#svap以降に分割

		spl_cpid = data[block_def['cpid']['offset']:]	#cpidで分割

		#CPPlを削除したデータを作成
		clean_data = b''.join([struct.pack(block_def['RIFX']['type'],h['RIFX'][0],h['RIFX'][1]-h['LIST'][1]+4,h['RIFX'][2]),
						spl_svap,
						struct.pack(block_def['LIST']['type'],h['LIST'][0],4),
						struct.pack(block_def['CPPl']['type'],h['CPPl'][0]),
						spl_cpid
		])

		fx=open(filepath, 'bw')
		fx.write(clean_data)
		fx.close()

必要なのはCPPl削除後のファイルなので、元のファイルを先にリネームしてやって、きれいになったファイルを元のファイル名で作成しています。
もう無理やりなんですけどね、とりあえず目的通り動いたからヨシッ!
もっときれいなコードをかける方はご教示ください。

追記

24/7/7追記
複数ファイルのD&Dに対応するためループ処理を入れました。

21/12/23追記
AEのバージョンによってデータの並びが違っていたので、オフセットの値をデータに合わせて書き換えるように修正しました。

参考サイト

https://qiita.com/katsuki104/items/3d0fbcb5c7da19d318bd
https://ohke.hateblo.jp/entry/2020/02/22/230000
https://expy-style.net/python/file-dd/


いいなと思ったら応援しよう!