Last active
November 25, 2017 17:51
-
-
Save earthnuker/4b0cd77a162d25dd5472883a411c056c to your computer and use it in GitHub Desktop.
IMG_Glitch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[DEFAULT] | |
reload=0 | |
header_size=1024 | |
iter_cnt=16 | |
file_cnt=1 | |
quiet=1 | |
join=0 | |
mode=reverse:1024 | |
[raw] | |
header_size=0 | |
file_cnt=1024 | |
;iter_cnt=64 | |
#1024 | |
#65536 | |
;256 | |
;1024 | |
;131072 | |
;65536 | |
;8388608 | |
;4096 | |
;1024 | |
quiet=1 | |
reload=1 | |
join=0 | |
;mode=copy:int(divmod(1.5**n//5,len(data))[1])|remove:int(divmod(1.5**n//5,len(data))[1]) | |
iter_cnt=128 | |
mode=copy:256|remove:256 | |
;mode=copy:4096 | |
;mode=add:1024|remove:1024 | |
;mode=copy:1|remove:1 | |
[wav] | |
header_size=1024 | |
iter_cnt=1024 | |
file_cnt=100 | |
reload=0 | |
quiet=0 | |
mode=reverse:65536 | |
[bmp] | |
file_cnt=1 | |
header_size=4096 | |
iter_cnt=512 | |
reload=1 | |
quiet=1 | |
mode=copy:16|remove:16 | |
#invert:777777 | |
[gif] | |
reload=0 | |
header_size=1024 | |
iter_cnt=n | |
file_cnt=1024 | |
mode=flip | |
[jpg] | |
iter_cnt=1 | |
reload=1 | |
header_size=1024 | |
file_cnt=1024 | |
mode=flip | |
[png] | |
file_cnt=1024 | |
header_size=8 | |
iter_cnt=1 | |
reload=1 | |
mode=flip | |
[mp3] | |
iter_cnt=65536 | |
reload=0 | |
mode=replace | |
[avi] | |
iter_cnt=512 | |
#65536 | |
#8388608 | |
header_size=65536 | |
reload=0 | |
mode=randomize:1024 | |
#1024 | |
[bin] | |
iter_cnt=65536 | |
#8388608 | |
#65536 | |
#8388608 | |
header_size=0 | |
mode=copy:128 | |
#536870912 | |
[wmv] | |
reload=0 | |
header_size=65536 | |
iter_cnt=4096 | |
#65536 | |
#4096 | |
#1024 | |
mode=flip | |
[m4v] | |
iter_cnt=4096 | |
#65536 | |
#8388608 | |
header_size=65536 | |
reload=0 | |
mode=copy:2|remove:2 | |
#1024 | |
[smc] | |
iter_cnt=1 | |
header_size=1024 | |
reload=0 | |
mode=flip | |
file_cnt=4096 | |
[nes] | |
iter_cnt=128 | |
header_size=1024 | |
reload=0 | |
mode=flip | |
file_cnt=128 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random,os,sys,configparser,glob,time,datetime,argparse,mmap,io,re | |
from zlib import crc32 | |
if len(sys.argv)<2: | |
print(sys.argv[0],"<input file>") | |
exit(-1) | |
t_s=time.time() | |
dt=lambda :datetime.timedelta(seconds=time.time()-t_s) | |
def fixpng(data): | |
data_handle=io.BytesIO(data) | |
ret=bytearray() | |
pngsig=bytes([ 0x89, 0x50 , 0x4e , 0x47 , 0x0d , 0x0a , 0x1a , 0x0a ]) | |
sig=data_handle.read(8) | |
if sig!=pngsig: | |
return | |
ret+=sig | |
fix=0 | |
while 1: | |
csize=int.from_bytes(data_handle.read(4),'big') | |
cn=data_handle.read(4) | |
data=data_handle.read(csize) | |
cs=int.from_bytes(data_handle.read(4),'big') | |
ncs=crc32(cn) | |
ncs=crc32(data,ncs)&((1<<32)-1) | |
if cs!=ncs: | |
fix+=1 | |
ncs=ncs.to_bytes(4,'big') | |
chunk=csize.to_bytes(4,'big')+cn+data+ncs | |
ret+=chunk | |
if cn==b'IEND': | |
break | |
if data_handle.tell()==len(data_handle.getbuffer()): | |
break | |
ret+=data_handle.read() | |
print("Fixed {} checksums".format(fix)) | |
return ret | |
def flipbit(data): | |
offset=random.randint(headersize,bs) | |
byte=offset//8 | |
bit=7-(offset%8) | |
try: | |
data[byte-1]^=1<<bit | |
except: | |
print(byte,len(data)) | |
raise | |
return data | |
def swap_data(data,size=1024): | |
if extra!=None: | |
size=extra | |
o1=random.randint(headersize,(len(data)-size)-1) | |
o2=random.randint(headersize,(len(data)-size)-1) | |
data[o2:o2+size],data[o1:o1+size]=data[o1:o1+size],data[o2:o2+size] | |
return data | |
def replace_data(data,size=1024): | |
if extra!=None: | |
size=extra | |
o=random.randint(headersize,(len(data)-size)-1) | |
toadd=data[o:o+size] | |
o=random.randint(headersize,(len(data)-len(toadd)-1)) | |
data[o:o+len(toadd)]=toadd | |
return data | |
def randomize_data(data,size=1024): | |
if extra!=None: | |
size=extra | |
toadd=bytes(random.randint(0,255) for x in range(size)) | |
o=random.randint(headersize,(len(data)-len(toadd)-1)) | |
data[o:o+len(toadd)]=toadd | |
return data | |
def add_data(data,size=1024): | |
if extra!=None: | |
size=extra | |
toadd=bytes(random.randint(0,255) for x in range(size)) | |
o=random.randint(headersize,(len(data)-len(toadd)-1)) | |
data=data[:o]+toadd+data[o:] | |
return data | |
def copy_data(data,scs=1024): | |
if extra!=None: | |
scs=extra | |
o=random.randint(headersize,(len(data)-scs)-1) | |
toadd=data[o:o+scs] | |
data=data[:o]+toadd+data[o:] | |
return data | |
def clone_data(data,scs=1024): | |
if extra!=None: | |
scs=extra | |
o=random.randint(headersize,(len(data)-scs)-1) | |
toadd=data[o:o+scs] | |
for _ in range(8): | |
data=data[:o]+toadd+data[o:] | |
return data | |
def remove_data(data,scs=1024): | |
if extra!=None: | |
scs=extra | |
o=random.randint(headersize,(len(data)-scs)-1) | |
del data[o:o+scs] | |
return data | |
def reverse_data(data,scs=1024): | |
if extra!=None: | |
scs=extra | |
o=random.randint(headersize,(len(data)-scs)-1) | |
data[o:o+scs]=data[o:o+scs][::-1] | |
return data | |
def invert_data(data,scs=1024): | |
if extra!=None: | |
scs=extra | |
o=random.randint(headersize,(len(data)-1)) | |
data[o:o+scs]=bytearray(map(lambda x:x^0xff,data[o:o+scs])) | |
return data | |
def wordpad(data): | |
repls={ | |
b"\x07":b"\x20", | |
b"\x0a":b"\x0d\x0a", | |
b"\x0d":b"\x0d\x0a", | |
b"\x0b":b"\x0d\x0a", | |
} | |
return re.sub(b'|'.join(re.escape(key) for key in repls.keys()),lambda k: repls[k.group(0)], data) | |
config=configparser.ConfigParser() | |
config.read("glitch.ini") | |
fn=sys.argv[1] | |
files=glob.glob(fn) | |
if not os.path.isdir("glitch_out"): | |
os.mkdir("glitch_out") | |
for fn in files: | |
n=0 | |
fmt=fn.split(".")[-1] | |
if fmt=="jpeg": | |
fmt="jpg" | |
try: | |
configd=dict(config[fmt]) | |
except KeyError: | |
configd=dict(config['DEFAULT']) | |
do_mmap=False | |
fs=os.stat(fn).st_size | |
with open(fn,"rb") as f: | |
if not do_mmap: | |
data=bytearray(f.read()) | |
else: | |
data=mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) | |
fs=len(data) | |
bs=fs*8 | |
while 1: | |
headersize=eval(configd['header_size']) | |
end=eval(configd['file_cnt']) | |
cnt=eval(configd['iter_cnt']) | |
reload=eval(configd['reload']) | |
quiet=bool(int(configd['quiet'])) | |
join=bool(int(configd['join'])) | |
chain=configd['mode'].split("|") | |
try: | |
extra=eval(configd['extra']) | |
except KeyError: | |
extra=None | |
if reload: | |
with open(fn,"rb") as f: | |
if not do_mmap: | |
data=bytearray(f.read()) | |
else: | |
data=mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) | |
n+=1 | |
print(dt(),"F:",fn,"OF:",n,"/",end) | |
for itn in range(1,cnt+1): | |
for mode in chain: | |
extra=None | |
if ":" in mode: | |
mode,extra=mode.split(":",1) | |
if ":" in extra: | |
extra,s=extra.split(":",1) | |
#if extra=="r": | |
extra=eval(extra) | |
if not quiet: | |
if itn%100==0: | |
print(dt()) | |
print(mode,extra) | |
print("F:",fn) | |
print("OF:",n,"/",end) | |
print("OFS:",len(data)) | |
print("IT:",itn,"/",cnt) | |
print("-"*10) | |
if mode=="flip": | |
data=flipbit(data) | |
elif mode=="swap": | |
data=swap_data(data) | |
elif mode=="replace": | |
data=replace_data(data) | |
elif mode=="add": | |
data=add_data(data) | |
elif mode=="wordpad": | |
data=wordpad(data) | |
elif mode=="copy": | |
data=copy_data(data) | |
elif mode=="remove": | |
data=remove_data(data) | |
elif mode=="reverse": | |
data=reverse_data(data) | |
elif mode=="clone": | |
data=clone_data(data) | |
elif mode=="invert": | |
data=invert_data(data) | |
elif mode=="randomize": | |
data=randomize_data(data) | |
else: | |
exit("unknown mode '{}'".format(mode)) | |
dir,fname=os.path.split(fn) | |
dir=os.path.join(os.getcwd(),"glitch_out") | |
ext=fname.split(".")[-1] | |
fname=".".join(fname.split(".")[:-1]) | |
if not join: | |
ofn="glitched_"+fname+"_"+str(int(n)).zfill(5)+"."+fmt | |
w_mode="wb" | |
else: | |
ofn="glitched_"+fname+"."+fmt | |
w_mode="ab" | |
ofn=os.path.join(dir,ofn) | |
data_fixed=data | |
if fmt=="png": | |
data_fixed=fixpng(data) | |
if data_fixed: | |
with open(ofn,w_mode) as of: | |
of.write(data_fixed) | |
if n==end: | |
break | |
print("Done in",dt()) | |
#input("Press enter to exit...") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment