Created
January 18, 2019 16:32
-
-
Save tjwei/55d19562cdd63c377294e73d02397a89 to your computer and use it in GitHub Desktop.
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
def H2str(h): | |
return chr(h&0xff)+chr(h>>8) | |
f=open("aaa.gif", "wb") | |
f.write("GIF89a") | |
f.write("\x00\x01\x00\x01") | |
f.write("\xF7\x01\x00") #GCT | |
f.write("\xff\x00\xff") | |
f.write("\xff\xff\x00") | |
f.write("\n=1") | |
f.write("\r\n\x00") | |
f.write("\xff\x00\x00"*252) | |
f.write(",") #image start | |
f.write("\x00\x00") | |
f.write("\x00\x00") | |
f.write("\x01\x00") | |
f.write("\x01\x00") | |
f.write("\x00") #LCT | |
f.write("\x08") # LZW code size | |
f.write("\x03") #length | |
f.write("\x00\x13\x00") | |
f.write("\x00") # end of image | |
f.write(";") #end of gif | |
f.write("\r\n\r\nprint 'hello'") #end of gif | |
f.close() | |
from struct import unpack | |
from PIL import Image | |
im=Image.open("face.gif") | |
dcodes=[] | |
def decodes(buf): | |
global dcodes | |
ctable=[[i] for i in range(258)] | |
oldcode=[] | |
rtn=[] | |
bwidth=9 | |
bits=0 | |
n=0 | |
for c in buf: | |
n=(ord(c)<<bits)|n | |
bits+=8 | |
if bits >= bwidth: | |
x=n&((1<<bwidth)-1) | |
#print "x=",x | |
n>>=bwidth | |
bits-=bwidth | |
dcodes+=[x] | |
if x==256: | |
#print "restart",n,bits | |
ctable=[[i] for i in range(258)] | |
oldcode=[] | |
bwidth=9 | |
continue | |
elif x==257: | |
print "end" | |
pass | |
elif x<len(ctable): | |
thiscode=ctable[x] | |
#print "case 1", x | |
if oldcode: | |
ctable.append(oldcode+thiscode[:1]) | |
else: | |
thiscode=oldcode+oldcode[:1] | |
#print "case 2", x | |
ctable.append(thiscode) | |
#if len(rtn)<100: | |
#print x, thiscode, len(rtn), len(ctable) | |
#if len(rtn) > 7600: | |
#return rtn | |
rtn.extend(thiscode) | |
if len(ctable)==(1<<bwidth): | |
bwidth=min(bwidth+1, 12) | |
oldcode=thiscode | |
return rtn | |
colortable=[] | |
with open("face.gif") as f: | |
header, screensize, info=f.read(6), f.read(4), f.read(3) | |
print unpack("HH", screensize) | |
print "GCT %x, BG %x, %x"%unpack("BBB", info) | |
for i in range(256): | |
colors=unpack("BBB", f.read(3)) | |
colortable.append(colors) | |
if ord('\n') in colors: | |
print "\\n in colors!!", colors | |
print "blocks" | |
btype=unpack("B", f.read(1))[0] | |
while btype!=0x3b: | |
print "blocktype %x"%btype | |
left,top,width,height,lct=unpack("HHHHB", f.read(9)) | |
print left,top,width,height | |
if lct: | |
print "LCT!!!" | |
break | |
codesize=unpack("B", f.read(1))[0] | |
print codesize | |
blen=unpack("B", f.read(1))[0] | |
codestr="" | |
while blen: | |
#print "blen", blen | |
codestr+=f.read(blen) | |
blen=unpack("B", f.read(1))[0] | |
btype=unpack("B", f.read(1))[0] | |
print "btype=%x"%btype | |
break | |
nlchars='\n\r' | |
import pickle | |
def encodes(codes, force_restart=[], stop_at_n=True): | |
tmp=[0,0] | |
rtn=[[], ""] | |
def addcode(code): | |
if stop_at_n and rtn[1] and rtn[1][-1] in nlchars: | |
return | |
rtn[0].append(code) | |
tmp[0]|=(code<<tmp[1]) | |
tmp[1]+=bitwidth | |
while tmp[1]>=8: | |
rtn[1]+=chr(tmp[0]&0xff) | |
if stop_at_n and rtn[1][-1] in nlchars: | |
return | |
tmp[0]>>=8 | |
tmp[1]-=8 | |
table={(i,):i for i in range(258)} | |
prefix=tuple() | |
bitwidth=9 | |
addcode(256) | |
for k in codes: | |
if stop_at_n and rtn[1] and rtn[1][-1] in nlchars: | |
return rtn[0], rtn[1] | |
pk=prefix+(k,) | |
if pk in table: | |
prefix=pk | |
else: | |
table[pk]=len(table) | |
addcode(table[prefix]) | |
if len(table)>4096 or len(rtn[0]) in force_restart: | |
addcode(256) | |
bitwidth=9 | |
table={(i,):i for i in range(258)} | |
prefix=tuple() | |
elif len(table)>(1<<bitwidth): | |
bitwidth+=1 | |
prefix=(k,) | |
if len(rtn[1])>3000000: | |
return rtn[0], rtn[1] | |
if prefix: | |
addcode(table[prefix]) | |
addcode(257) | |
return rtn[0], rtn[1] | |
jj=decodes(codestr)[:width*height] | |
da=[x for x in im.getdata()] | |
print "encode" | |
fr=pickle.load(open("fr2", "rb")) | |
fr[41313]=1 | |
cnt=0 | |
while 1: | |
kk, kstr=encodes(jj, fr) | |
if cnt>0 or kstr[-1] not in nlchars: | |
break | |
lkk=len(kk) | |
j=3 | |
fr2=fr.copy() | |
while kk[lkk-j]==256 or kk[lkk-j-1]==256: | |
j+=2 | |
fr[lkk-j]=1 | |
cnt+=1 | |
kk, kstr=encodes(jj, fr, False) | |
#kk2, kstr2=encodes(jj, fr2, False) | |
print len(kk), len(kstr), kstr.find('\n'), kstr.find('\r') | |
iii=0 | |
def makegif1(num, step=1): | |
global iii | |
for i in range(iii, iii+num, step): | |
s=kstr[i:i+step] | |
outf.write(chr(len(s))) | |
outf.write(s) | |
iii=i+step | |
def makegif(end, step=254): | |
global iii | |
for i in range(iii, end, step): | |
s=kstr[i:i+step] | |
outf.write(chr(len(s))) | |
outf.write(s) | |
iii=i+step | |
with open("face3.gif", "wb") as outf: | |
outf.write(header) | |
outf.write(screensize) | |
outf.write(info) | |
for c in colortable: | |
outf.write(chr(c[0])+chr(c[1])+chr(c[2])) | |
outf.write(",") | |
left,top,width,height,lct | |
outf.write(H2str(left)+H2str(top)) | |
outf.write(H2str(width)+H2str(height)) | |
outf.write(chr(lct)) | |
outf.write(chr(codesize)) | |
makegif1(28) | |
makegif(9000) | |
makegif1(66) | |
makegif(17000) | |
makegif1(80) | |
makegif(25000) | |
makegif1(109) | |
makegif(33000) | |
makegif1(4) | |
makegif(len(kstr)) | |
outf.write(chr(0)) | |
outf.write("\x3b") | |
outf.write("""\n=1 | |
print '''Hello and smile! | |
It is a picture and it is a python script too. | |
tested on | |
Python 2.7.3 (default, Sep 26 2012, 21:51:14) | |
[GCC 4.7.2] on linux2 | |
This proof of concept is made by TJW (http://weijr-note.blogspot.com) | |
The picture is from http://www.flickr.com/photos/theklan/1361277704/ | |
with a CC-SA license | |
Now, enjoy the game if pygame is installed | |
''' | |
from pygame import *;R=range;W,H=10,20;E={198:0x7fff,46:0xff00,39:255,102:0xffff | |
,71:0xffff00,108:0xff00ff,15:0xff0000};B=[[15 if j==H else 0]*W+[15]*3 for j in | |
R(H+3)];S=n=0;import sys,random as C;C=C.choice;e=[1];O=lambda:(lambda Z:([(z/4+ | |
1,z&3)for z in R(8)if(Z>>z)&1],3,-2,Z))(C(E.keys()));P,X,Y,Z=O();T=USEREVENT+1 | |
L=lambda P,X,Y:[1 for(i,j)in P if B[j+Y][i+X]];d=display;init();F=d.set_mode(( | |
400,800));time.set_timer(T,100);w=key.get_pressed;a="GAME OVER, score " | |
while(d.flip()or e.__setitem__(0,event.wait().type)or e[0])!=QUIT: | |
if e[0]==T:K=w();U=X+(-1 if K[K_LEFT]else(1 if K[K_RIGHT]else 0));V=Y+1 if K[ | |
K_DOWN]else Y;Q=[(j,3-i)for i,j in P]if K[K_UP]else P;(P,X,Y)=(P,X,Y)if L(Q,U,V | |
)else(Q,U,V);n%5 or L(P,X,Y+1)and(Y<0 and sys.exit(a+`S`)or[B[j+Y].__setitem__(i | |
+X,Z)for i,j in P]);(P,X,Y,Z)=(P,X,Y,Z)if n%5 else(O()if L(P,X,Y+1)else(P,X,Y+1, | |
Z));n+=1;D=[z for z in B[:H]if 0 in z]+B[H:];l=len;s=l(B)-l(D);(S,B)=(S+2**s,[B[ | |
-1][:]for j in R(s)]+D)if s else(S,B);[draw.rect(F,E[Z]if(i-X,j-Y)in P else c,(( | |
i*40,j*40),(40,40)))for i,j,c in[(z%W,z/W,E.get(B[z/W][z%W],0))for z in R(W*H)]] | |
""") | |
ss=open("face3.gif", "rb").read() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment