mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-24 00:04:09 +03:00
Merge pull request #35 from fluggo/master-1.7.8x
Add Python 3.2 support
This commit is contained in:
commit
b48257e259
BIN
Images/lena.fli
Normal file
BIN
Images/lena.fli
Normal file
Binary file not shown.
BIN
Images/lena.ico
Normal file
BIN
Images/lena.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
Images/lena.psd
Normal file
BIN
Images/lena.psd
Normal file
Binary file not shown.
BIN
Images/lena.tar
Normal file
BIN
Images/lena.tar
Normal file
Binary file not shown.
175
Images/lena.xpm
Normal file
175
Images/lena.xpm
Normal file
|
@ -0,0 +1,175 @@
|
|||
/* XPM */
|
||||
static char * lena_xpm[] = {
|
||||
"128 128 44 1",
|
||||
" c None",
|
||||
". c #CC9966",
|
||||
"+ c #663333",
|
||||
"@ c #996666",
|
||||
"# c #CC6666",
|
||||
"$ c #CC9999",
|
||||
"% c #FFCC99",
|
||||
"& c #996633",
|
||||
"* c #FF9966",
|
||||
"= c #663366",
|
||||
"- c #FFCCCC",
|
||||
"; c #CCCC99",
|
||||
"> c #FF9999",
|
||||
", c #993333",
|
||||
"' c #333333",
|
||||
") c #CCCCCC",
|
||||
"! c #996699",
|
||||
"~ c #CC6633",
|
||||
"{ c #666666",
|
||||
"] c #999999",
|
||||
"^ c #666699",
|
||||
"/ c #330000",
|
||||
"( c #663300",
|
||||
"_ c #330033",
|
||||
": c #999966",
|
||||
"< c #FFFFCC",
|
||||
"[ c #333366",
|
||||
"} c #660033",
|
||||
"| c #CC99CC",
|
||||
"1 c #9999CC",
|
||||
"2 c #660000",
|
||||
"3 c #FFFFFF",
|
||||
"4 c #CCCC66",
|
||||
"5 c #FFCC66",
|
||||
"6 c #666633",
|
||||
"7 c #993366",
|
||||
"8 c #FFFF99",
|
||||
"9 c #993300",
|
||||
"0 c #333300",
|
||||
"a c #FF99CC",
|
||||
"b c #CCCCFF",
|
||||
"c c #CC9933",
|
||||
"d c #CC6699",
|
||||
"e c #000000",
|
||||
".....*...*.%*..#&@#&@&#&#&#.&#.#.#.#.#.#..#.*.#...#..#.#.#.#..#..#..#..#..#.#.#@#.>..>...*..*...*....%%%%.&&.@.#.@.#..&#.~.#&#$.",
|
||||
">%*..*.*..*%.*.&#@&#@#&#&#&#*&.#.#.#.#.*#..#&.~.#.#.#.&.#.#.#.#.#.#&.#..#&.@.@&#&#.>.*.*...*..*..*...%%%%%&&~@#&#.@&##.&#.#.@.>@",
|
||||
"...>...*.*.>.%*&#,&#&#&@&#.&#.#.#.#.~.#.#.~.>.#.#..~.#*.~.&*.#.*&*.#..#&.#.##.#@&#.$.>.>.*..*..*.....%%;%%@&@.#.@.#..&#..&#.#@+(",
|
||||
".*...*...%*.*.>&&@@#@&##&#.#&#.~.#.#.#.#.##.#&*.~.#..#.#.#.#.#.#.#.#~.#.#.#&.#&@#&#.>.....*..*..*.*...%%%%%&.&@.#&#.#.#.#$.$&+++",
|
||||
"..>.*.*.*.%.>.~&#&#&#.@&#&#&.#.#.#..#.~.~.*.~>&>.#.#*.#.#.~.~.#.#.~.#.*&*.#.#.#.#&#..>.>*..>..*.......%%<%%$&#.#&$&#.&#.&>@,++2+",
|
||||
".*.%...%*.*..*.#&@#@&##&#&#&#&#.&.#*.#.#.#.#*.~*#.~.#~.~*#.#*#.*.#.#.#.#&.#.#.#&@.##.*..%*..*..*>.*.....%%%%&&&.#~.#.#.#.$&+++++",
|
||||
"..>.*.*.%*.*..*#&,&#@&#&#&#.#.~#.~.&>.~.~#*&#~#.~>#.~$~$&.~..#.#~.~.~.#.#.#.#&$#&#&$.>.>..%*.>....*.....%%%-.@#&.#&#.#.$$,++++++",
|
||||
"..*.*%.*%.*.>..#&@#&##&#&#&#&.#.#.#.~.#.*.#.*.~.~.#.#.~.##&#.~.#.##.#*&*~.#.#&#.@#&>.>%.*>.%..*.>..*.*..%%%%%&&&.#.&#&#.@++++'=+",
|
||||
".*...*.*.*.*.*.~#@&#@&#&#&.#~.#&*&*&#.~#.~*#~#.#*#.~.#&>..#.#.#...#.#.#.#.#..#.#&#.#..>...*.*..%*..>...>.%<%-%@.&#.#.$@@++++++=+",
|
||||
".%.*%.%*.%.*.*.&&,&#&#@&#&#.#&.#&*#.~.*.#..#.*~.#.##..#&..&*&#.##.~.#~.#~.#~#.#.@#@.#..>.>..*.*..>.*.*....%%%%.&&#.#&$,++++=+='+",
|
||||
"*>.*.*..**..*>.#,@#@#&#&##&#&#*&>&*#.#~.#~.#.#.#*#.&#&.#@#.@..#..@.#..#.#~..#.#&#&#.>.>...*.$..*.*...*.*.>%%%-%&&@&$#@++/++'++=+",
|
||||
"..%*.%*...*.*.*&,&#&@#&#&&#.#.#.#&.~#.#.#.~.#.#..#$#$.$...$&@.@.#.@.##.#.##.##.#.@#.#..*.>.%*.>...>.#.#....%%<-.&#.@&+++=+=+=+=+",
|
||||
"*.*.*.*.*%*.*.*&#,@#&##&##&~#&*&*#*&*&*&*@.#.~.#$..$.$.-$%$-%$.@.@.&..#*#.#*&#&##&#.#.>...*....*>.*.*.*.~..%%%%%@@.@++++++=+=++=",
|
||||
"%..%*..*.*.*..*&&&,@#&##&#.#.#.#.#.#.#.#.#.#.#..@>@.$$$;$%$.$-$%$.#@.#..#.##.##.#@&#$.>.>.>.*>.....*.~.*....%<%<.$+++/+=+=++=/++",
|
||||
"*.*..~.~.%*.*.*# #&,&#&#&#~.#~.~#.#*&*#..@.#.$.$$.$.$;$;$%$%$-.$.&@#.#~.##.#&##.#.#....*...*.>*.#..#.~....<%%-&+++++'=+[++=++",
|
||||
".%*.*.&*.*%*.*. @#&#&#.#&#.##.~.#.#..>.#.$&#$@.$$:$$;$;$;$;-;-$.@&#$#.#&###&@.#..#.>..>.>..~..*#*.*.~...%%<-@+++=++=++=++=+",
|
||||
"*.%*&,&*.*.*.* @#&##&#.~&*&>~.#.>@#&.@#.@$.@$.$.$.$;$;%-;.)%-%$&@.##.#.@.##&#.>.*.#.#.*&*.*.*.#.#..*...-%-+++/+{++_++=+}+",
|
||||
"*.>.~&~..%*.*. &#&#&#&#.##&.#~#&*&##.@.#&$#.@.$.$;$.%).;-;$;$)%$&@&@#.##,@@.#..>.>..>.>.~.*.#.#>.>.#.*.-$+/+=+=+=++=+=+_+",
|
||||
".*.&#(#.**.%*. @#&#&##.#&*#.#..##.#&#@.$.$@>$$.$.$%]%;$;;-;)%)%--&@&@&#&#&##.#..*.#.#..>..~.*..#.*...#..++='+++=++=+'+++@",
|
||||
"%.#&~&~..*c*.* #@&#&#&#.#&*&#*#.&#.#.#@##.&.@.$$.$%$$;$%]%)$;$;-<-%@&@$&##@&#.>.>.#.#&#.*.*.*.>*.~.*..>++++=+=++'=+++=++$",
|
||||
"*.~&,&#.*%.*.*. &#@#&#.#&#.#.#.#&#&#&@.#..@$#.#.@.$.]%;-;-;$;$;-;)--<$@#&,@&##.*.*.>.#&#&$..*.#.*.#.*$.$&++/+++='=+}+=++@$$",
|
||||
".#@&,&#.*.*%*.*& @&#&#@&#.#.#.~&*.#&#.##&@@.#.@.#.$.$.$.$%$;$)-3))-;;-;-&@@@#@#&#.>.*.#.@(,$#...*#.**.*..@++++!'+}+=+=+@+@@$.",
|
||||
".&,&#&&>.*..*.#&#@,&#@&#&#&#&#&#.#.##&#&#.#.#&$.#.$.@.$.$$-$;$$%)%-;-;3;)<-)&@&@&,#.~.*>.>#&,+.@**.*.~>.#.>.+++'+++=+=+=++@@@.$.",
|
||||
"&#&#&,#..*%*.*.,&,@@#@#&##&#.#&#&#.&~#.##&#&#.#$.#.>.#.$.;.$$;-;-)-);)-)<)%3-++@@&@#.*.*..>@,+@@..#*.*~**.>+++_+='++=+=+=++@.$..",
|
||||
"&,@,&@&>.*.%.>.#&+&#&@&#&#&#&#.#.#.#&#~.#.#.$&#.#..#.$.$.$$.-;--)%)););););-<-&+,@~@*.**>.#&+2+@>*.*#.*.#>&2+++=++=++_+++@@$$...",
|
||||
"&#&@,#&>.%**.*.&,@,&@#&@@#&#.#&#.~#.#&#&#&#&#.@.#.$.@.@.$.$;-$-;-;-)-;-);-);-)-$+@&#.*..*.>@++++@.#.**.>*$,+/=+=++'=+'+=+@$$.$..",
|
||||
"@,#&@&#.*..%.>.#&@@,@##&#&##&#.#.#&#&#&#.##.#.$.$.#..#.@$.--;%)$-)%));)<))<)-<)%@+@.#.**.>.#++++#@.>&#.>.@++++=+'+++=+++@$.@..-.",
|
||||
"@&@,&,&>..**.*.#&,&#&@&@#&#&#.#&>&#&#.#&#.#.#.#.#.>@.@.$%).-$;-;$-;-%)-)%)-;)%)-$+@&.*..*.#@+++++.@...$.#++}=+=+=+=+++++$$$.$...",
|
||||
",#@,@&#..*...>&#@+&@,@#&#&#.#&#&%#&.#&##.#.#.#.#...#&$.-.-;$;$-;)-))-;-;-;)-;3;3-@@&$.*.*.>&++++/@.-%%$$+++++++=+'+=+++$.$..$.$.",
|
||||
"@,&#@,&#%.%*.*.&,@,&#&#&#&#&#.#.>&#&#.#&#&#.#.@.#@@..$%$%$.-;$;-;-;-;--)--;)-;);-$(#..*.>.>@++/++--;-<<)/'+[+=+++=++'+@$&$.$%.$.",
|
||||
"@,@&,&..*.*%..>&,&@@,@#@#&#&#&#%>&#&#.#.#.#.#.#..&@.$%$%]%).-;$;-;$)%$;-%)-;))<)3-@@...*..#@++=@-)%)%)-<{+[++{+=+='}+@:$.$..$.>.",
|
||||
"@&#@#,&#.%.*.*.&,@,@&&#&@#&#.#&%>&#&#&#&#.#.#.@>&#.$%$.-.$;$;-;$;$;-)--)-;-)%);)))%@..*.*..@++]-]$<);<)-]'='=++++=@++$.$..$..$.$",
|
||||
"#&,&#&#.**%.%*#&,&&##&#&#&##&&#%.#&#&#&>&#&.#..#&-*$.$.-$-.)$.-$;$-.;-;.-)%;);-;-)).$...*>&&+$)$))--;)%)$+'+=+=++'}'$$$.$.%$....",
|
||||
"#&@#,~&*...*..*&@,@&&#&##&#.#&.%*&#&#.#.#.#.&#.&.>%.$.$.;-$%$).-$;-$;--);$);-);)-))-$.>..~@.%;;-;));-;3-{+'+++=+=++@@$$..$...$$.",
|
||||
"@&#&##&*.*5.%*.#,&@,&#&#&##&#&>%#&#~@#&#@.##.@.>..#.$%$-$.).$;$;%$;-.;-%)%$;-;-;);-;%$....%--$3)-;-));-)++=+[+/++/+@$.$$..$%>..>",
|
||||
"~@#&,&#*.%*.*.*&@,&#&#&#&#&#@&%.#&#&~.#&#.&#.#..>.$.%$.%$.-;$.$$%$.-;$.$;$;$;-;-)$)-%$.$-%-;%;-;-)-;-3%)'+'++=+=++@$$$.%$..$..$.",
|
||||
"@&###&#.*.5.%.>&,@@&#&#,&#@~&#%..~#&#&#&#$&#..>..#.>$.$.$%$.-;%.-.$%$%)%$;-)%$);%).]%-%%$.-;-);-)%)%;-3-+'=+_++++@$$.$.$..$.>..$",
|
||||
"~@&#~#&*..%**.*.,(#,&#&##&#&#&%.>.*&#&#.#.#.#.#..#...$.-.$.$..$.%;$.%$.-;$%)$;$$;$;-;$)%-;-$%)-;-;-)-;-]++'+'=+++@.$$.$.>...$.>.",
|
||||
"#&#&,&#.*..%.*.#@@&@&#&#&##&#&-%..#.#&#&#.#.$..#.$.>.$.$.-;%$%.-..$;.).$%$-.-$;$;$;$;$;-);-;)-;-)%$%)%-{+_=+=+'+@$$..$.%$.>..$.$",
|
||||
",@&##,~*.5*%*.*&,@,##&,&#&#@&~%.**.~&#&#&#.#.#..>.$.$%$.$.$.$.$.$%$.$%$%$;$:-$-.$%$;-;-;$)-)%)-;-$:$.)-+'+'=+++@@.$.$.$...$.>.>.",
|
||||
"&#,&#&#.*..%.*.#,&@&#&#&#&#&#&%..*&*#&#&>$.#$.#..$.#.$.-$.-.-..-..$%$.-$;-$$%]$;-;%)%))););$)%)%-.$@;$$++=++=++@$.$.$..$%.$..$.$",
|
||||
"@&#&#&#..*.*.*.&@,@#&#&,#&#&&#%.*.*.&#.#.#.#&$.#.>.$.$.$.$$.$$$.$$$%$$%$.$;$$.$$;$%$;)%)-);-;-;-.).$$-'+'+='+'@@.$..-.>.$...$...",
|
||||
"&#@,#~#*.%5%.%*#+,&@,#&#&##&#.%*.*.*~&#.>@#.>..#&$.#$$$$$.$$@@$$$.$$$$:$$-.$;-;-%;)%)$;);-)-;--$;@.@;-++=+=+++@$.$.$..$..>$..$>.",
|
||||
",&#&#&&*.*.*.*.~@@,&#&#&#&#&,.%%..*..#.#.#.#.>.#.$#..$&@@@@@$$@$-$$]-$$+.{$%-$;-%$;-;-;-)-;--;-.$@:@-$/++_+=++@$.$..$.$.$..$..$.",
|
||||
"@&#,##~.*.%.%*>&,@@,&#,&#&#&,.*.*.**.&#.#$#$.#.@*@.$>@$$@@@+$)@!]+@@@++{+$;$:-%]%)%$;-);;--;-%$@&+@%-+'+=++++@$$.$.>.%.$.$..$..$",
|
||||
"&#&&#&#*..5*..*&,@,@&#&#,#&#&&%%%*.*.#.#&#.#.$.#.$#.@$@@@{!@!@!+=$=@'+++@$$-$%-;)-;).)%-%)%$.@&@&$%)+++'+==++.$.$%$.$$.$.%$.$...",
|
||||
"#&#@~#..*.*%%*.#@+#@#&#&&#&,&~%%5*.~.~&#.$#$&#..#.$#$@$@!@={=!!@[@[@=e+)$;-;);$%;$-;-);$<$&@6+@&]$-(++++=++++$$.$.$%.$..$....$..",
|
||||
"&#&#&##*.%..*..~#+&#&,###&#&#(%%%...>&@#.#.#.#.@>.@#$@@+@+=+!{=!!=+!++)@-]%$%)%$;)$;$%)%@]&@&@.$.)+++'++=+=+@$.$%.$.$.-.$.$$..$.",
|
||||
"@#&##&#.**%.%*.#&,@,@&#&,#&#&#.%5....#@>#$&#.$#.$$@$@=!==+=]!_+=@[+{+$$)%$);$;;-$-;---@@@@.:%.-$-++++=+=+++@$.#.$.%.$.$.$.$.$$.$",
|
||||
"&&#&#~#...5*%*.&,@,@#@#&#&#&&,&%%%%..@.$.,.#@&$@,$@+}@='=/={+=]!_!/!$]%$;).-$;$;)-$;.@{@@$-$..%%+/'++=+'=++@$$.%..$.%..$%$.$.$.$",
|
||||
"#&#&#&#**.*..**#@,&@,@#@#&##.#&%%%..#$##&#.&$.$$+@+!@=+!={=+={=@@_]$@-;$%$;$;$;$;-.$(+@${@:%.--+++++=+=++++@..$.$%.$.$%$.$.$.$$.",
|
||||
"#&###&#.%.%*%...,@,#&#&,#&,&#&#&%%%.&..#$#.>@#@@@@=@=+=!+_'+=+='!!{@)$--;$;$;$%;$)%]&@@@$@$$%.(+++++'+_+=+@$.$%..$%.$..$.%$.$..$",
|
||||
"#&@&#,&**.%.*%*&,@&@,#@&#&#&#&&9%%.>.#@..@.@.@@@@@@=_=+=@_+=@@!+!]@$).;$.-.$;$;-;-%-.@@@@@:-@++++++=@+'+++@@@.$.%$..$..$.$.$.$.$",
|
||||
"#&##&###..*%.*.~@,+#@&###~#&#.#&.%%.&.,.#&#$@$@+=+@=+=^@[+++=++!@]@)$%).).)$.).-;$;%.+@@@$@.6+/++++++=+=+@$&$%..$.$.-.$..$..$...",
|
||||
"&#&#&,&*.%.%*%*#&,@&#,@&@&#&#~&#&-%#.#&#&>.@@@}+=+={!==@!+'+'+@+$1$)$%$.$$.-;-%;-%-%$@++=@]$+/+=+{=+=/+++@$$.$.%.%..$.%$.%$..$.$",
|
||||
"#&@##&#.*%*.....,@,@@&##,#&#&>&#&%%&#&.@.@>@@+!+='+==+![$!+++@@$]$-$;$;$%$.$;$%-;-%%%$++@+$]+++=+++++'+++$@$.$.$.$$%.$.$.$%.$...",
|
||||
"&#&#&,&#..%.%*>&,@(##@#&#&#&#.#&#->.&#&>&@++!+=+=+=+[=+=@++/@$$$$]$).$..$;$-%-;%-%;%.$@+}{$$+'+=+={+=+++@@$.$..$...$..%.$.$..$.$",
|
||||
"&#&##&#*.*%*...#&@,@&#@#&##.#~&#..-&#..#$@@++++^+==+^=@!'=/@$$$-$$$-;-.$.$%$%$%-%--%%#@+}@]$@++=++=+++++$@.$.$..$.$.$.$;..;.$...",
|
||||
"@&#@#,&...%.%*.#&@,@#&#&#&#~$~#.##%#.@.$@++!_=@={+=+=='=+@{@.$;$)&$%$.$.-$%$%-;%)%%%-%@+++@${+={=++=+++@$$.$..:.$.$:$.$.$$.$.$$.",
|
||||
"&@&#&,#*.*%*%*.&,@@&@#@##&#&#.&#&$@.@.#@+!++@'+=+'=+=+=@'@$:$.$%-:-$.$.%>%$-.-%%-;-%%>@@+/@$++=+={++'++@@$$.$%$.;..$..$..$.$:..$",
|
||||
"#&#@#&@....%.%>&#(@#@&#&#&#&##*#@&#.#$@@+@_!_=+{=+={==+/+@@$.$;$$$..$%>.$>%$%-;.-%%)%-$+}+@)@++={+=++++$..$;$...$$..$:@.$:$.$$$.",
|
||||
"@&#&#~##..*%.*.&@@,&#@#@##~#.&#.>++&$.@+=+=@=+=++++='+^+]@-;-..-%$@&&#.>%>-.$%-;-)%%%$#++++-@+@+=+[+++@$@.$..$;..$.$.$.@.$$.@.$$",
|
||||
"&#@,@,&*.%..%%>~@(@@&#&#&@&##.*.#+2$@@@+!=^!'={+_+=@!@_+@:-.).;-.$.$.,(#.>$%$%%%$;-%.@@++++%@+=+{+=+++@$$.$....$;.$:.$.$.$.$$@.@",
|
||||
"@&&#&#@#.*%.*..&#@,@#&#&#~#&#&>.$@(@@@+@++=!+=+'@/=/@+'$@)$%$.-&@$$$.$&,&#.>.$;%%$@@&@#@+++]$++=+=+'++.@.$%$.$..$%.$.$.$:$$$:$@$",
|
||||
"##&#@9&..*%*%%*.,+#&#&#&#&@&>..>.$@++!=^!!/^+^+=1'+=++@:-.;-$%@@@+++++$.#.>.%%-;-$@+++@++++$@@++=+=++@$@.$.$..$..$$.$.$.$.$.@$:$",
|
||||
"&#&#&#,>...%.*..&,@,&#&&#&#..$..$+@+=@!@^]=@=+'+_!'+0+$.$;-%-+(+,++@@2+#.#*>.%-;@+++++}+++{$@@+++'+++@..$.$.$..$...$.$.$.$$$$$@$",
|
||||
"&,@,@(&.**%*.%*&,@,@&#,.,&#-.$.@$++^+^_=!@_'+==/^+_++@:.-.-%+@,++@++--(@~.#.>%%$++@@a+++=++$]@=+==+++.@$.$.$.$.$.>$.$.$$.@.:@@.@",
|
||||
"#&#&#,,...*%.*..@,&##&#&#@+,$$$(+/@=+=!+^1+[+'+='=+'+@$$.%-&@&,&@+@@$-#@#&#..)%6@+@@$7++++@@$@@++=+++$..$.$.$..$..$.$.$.$.@.$:$.",
|
||||
"@&#@,&@#.%.%*%.~#,&#&@.,+&@--%+++{!'=!=^+!+==+=+=+'+$..$;-&&$$@@&$.--%.$~#*.>%-@.$#$$,@+++!{$@@+=+'+@:$.$.$.$.$.$..$.$.@$:$.@..;",
|
||||
"#@#&@,&#.*5.%*..&@#&##.+#$$$@++@@'}'={=!!!'/'=+'=+++@-$%-&@...*$#$@&@$-.#.#.$%;$.$.@,+@}++@@|{++++++@$.$.$..$....$.@.$.@.@.;.%%%",
|
||||
"#&@,@,&#.*%*%.*.,,&#&#$#$$+@=+'+1$!==^={$1+=++=++/+$]$.-&&*#>.$.$.$.-.#.>.#*$-%-$.##@#@++++@$@+=+=+@.@...$.$.$.$.$.$.@.$.$.$%;.%",
|
||||
",@#&,+,.>.%*%.*.&#&#.@&$@!+!+==@!{^'==!!!!{+='/='+@@$--#&#...>.>.$.$.$%#*#.*$%-.$.$.#$,@+++@$@@++++@$.-$..$.$.$....$.:@&$%%%%%.%",
|
||||
"@&+@,&+...%.*%.#,#,@##$#$$|={={^{!+_=]={@$!+++=+++@$$%$&@.#*>.>%$%%$%$..>.#.>%--.*>##@@+}+{+|$+++++@....$..$...$.$.@.@.;%.;%.;5%",
|
||||
"@,&,@+,#.*%*%.*.&,&#.$@$+=+='=!+!{[='==!^/@!'++/+@]$--(,#.~.*..>.>.%$%>.*#*#$%-%$...>##+++++$]+++++$@.$..$.$$.$.@:$...$.-%.%%.;%",
|
||||
"@,@+,&+...*%*%.~#&,@@#$+!@^=!'!1'_+==+=+++]@+=+++$$$)++&#&>~>.>%%%$%..$.*.#..---..>.#$#+++++-$++++@.$...$...$.@...@.@.%;%%;%%%%%",
|
||||
"@+@@,+,@>%..%*..,#&#&@@$!{=!==!{=='+[+{=++$@@'/+$&--@+/@~#*~.>.$>%.%>.>.>*#~$%%-.>.#.#@,++++$$++++@$.$..$.$.$.:$.$.:..%%.%;.;%;%",
|
||||
",@(+,+&#..*%.%*&,@#@@$$+@!]={^@!{+=='_++++$@$@+/@$-)+/@@#.~**.>..>%$%..*#.~.#$-%...>$#++7+++1$++++@.$.%..$.@.$.@.$&$.;%%4%%%%;%%",
|
||||
"+,@@+,+&>.%*.*..&@&#$$+!@^===!1]|'+=+}{@+@$$+++]@%$+++/&###~#..>...>.>..#*#..%--.>..>@,+++++$$++++$.$.$...$.$.:$.@...%.%.%4;%%;-",
|
||||
"@@+,+,+..*.%*%*#,,@@@$@+!{={1{=$=/'+=+@+]@+@/'/$@%@'++@@~*~**>.$*>%..$*.~.#*@.-<..$#.@+++!+/$$@++@$....$...$.$.@.@.$%%454%%%;-%)",
|
||||
",@+@,++#$%*%.%..,@.#@@@=@!==!=^][+='/=@$@.++++$@:$+/+/@+@#*#*.*$..>.>..##*.#..--...>@,}++@+/$$$+(@@$.$..$.$.$.$.$@..%%%%4%;%;%)%",
|
||||
"@,@++(,....*%*..#,@@@$+@!{=@^+!!{|+={++=+@+/+@;$-@+'++@,#&*#.#.>*>.%>*#.*#.#.$%-.>.@$+++=++++$$/+.$.$.$..$.$:$...@.%%.4%%%;%%;%;",
|
||||
",@,@,@+.>.%..%*&&&,@@@@!@=_!='!!]1+={}'+!++++$-$]+/+++@@&#*~*>.>.>.>.$*.#&#&#&>.*..#@+=++++++$$+&$..$.$.$.$.@.$.$..;%%%4;%%;%-%%",
|
||||
"@,@,+&@...%*%*.>#+#@$@+!+=]=!=]!|!'+!@/++/@@@$6-++=+/+#@~#.#*~>*.#*.*.>.*..#.$%$.>$@+}+=@++++-@+@.$.>.$..@..$:@.@..%%4%%%;%;%;;%",
|
||||
"@+@@+,@.$*.%.%..&+&#@$+{!@=_{=!!{!!'@^++!@$$@@$+'+++++#@$~#*#.#.>.>>.>.#.>.%%-%$..#@++++!+@+($$@#.$.$..$.$.$..$..$.%%%;%;%%;-;-;",
|
||||
",@,+@+#..%.*%*.##,@@$@!+!{==={={=1@={@/+]$$$@@@+++=@++@&#.~*~**.#...*..>..>-.%>.>$.++=++@+++/$.@...$.$..$..@.$.@..%%.%5%;%;-%<%;",
|
||||
"++@+,+@.>.%.*%..&@@#@$+@!+!'==!!^!1+@'+@@$-@@]+++@++++#+##.#.#*.*.>.>.*.>..%$%%$.$@/+=+7@@++($@@$.$...$.@.:$.:.@..%%%;%<%%<;%-;%",
|
||||
"+,@+@,&$..*%.*.#&,@@@!+!+[=@^@[+^={|++.)$-+@$++{+=+!+++&#.~***#.#*.~.#..*$*>%$.$#@+++++=+@,++@:....$.$..$.$.@.$.@.%%%5;%;;%;%;-<",
|
||||
"++,++@,.>%.%%%.#&@#@$@=+!'===!{=^!!{@)@-%@@@+/+@}++++++@##.#~.**.#&#.~#.#&.#.,&@>$++++++}@++(@@@.$....$...$..@....%%%%%%%%;-<%;%",
|
||||
"+++@+@&$..*%*%*.@$,@@@@=+={^'|!{!!{+@$&3$&]$++=+++=+=+,+&#~.#*#.*>*~#.~~>&#.>$.$$}+}'+=+@@+@+&$.$..$..$.@.$:$.]@&%%;%4%;%;%<-;%<",
|
||||
"@++++@&>..%*.%.#&$+$@@'=+_=@=]=!^!={]$$;@$$++'/=+++@+++@@&#~.~.#.#.*#*#.*>%-*#$>@+++++++}@2@+&$.$..$..$:.$..$..$&%%%%%<%<%;%%;%%",
|
||||
"++7+,+@..>.%%*..#+@@d+@='='=^@[@^^@!$]$$@-+++++++=++=+@,,@~@~#*~.*>.~.#*#.>.>.>@+_+=+++@+@+@2+$..$..$..$.$:@:$@:@;%;8%;%;%-;%;%;",
|
||||
"=++++@&#.%.*%>..,@$@@+!+=$[@b{!{=^!]@$$$-+@+}{=+++++@++@,@#&#.#.#.#*#*#.#~##$#$,+=++{++@7@}@++.$..$..$.$.$.$.$.@.%%%%;%<%;%)%%%%",
|
||||
"+++++#@..*%.%*..@,$@@+!'_=='|^@1!+1@@{$-@++=++++++=+{+@++&#&#&>.#*.>..#.>..>.>@@/=+++++@+@+@++.$...$..$.$.$@:$@:@;%<%%<%%<%%;%;%",
|
||||
"+=++@@@#..*%.%>.@+@@+@@='@[=$^!]!^+1$+]$+++++=+=++++=+++++,#&##.#.#.>*.>.>$%$.++=+[+{++@+#+#++$.$..$.$.$:$.$$$.@&;<%;%;;%-<%%%%%",
|
||||
"+++++@..>.%*%..#@,@@=+^+=^+^]='1|]=]$@@+=+=++'+++++=+'+++&+,,&#.#....>.>%$.>$#(++=+++++@@+7@@(-.$.$..@.$.$@:@$@].-%;<%<%;%%)%;%%",
|
||||
"+=}++@@...%.*%*.@+@+++!+'='_!]={!!]!!{!+'=+=+='@+++++=@+++(+(,#&#.#>..%.>%$.$@+++'={'++@+@+@@+.$..$:$.@$.$.$.@:@:%<%;%%<%;%%%%..",
|
||||
"+++++#@#.*.%*%.#+@$@=@==+='=]|={!^|{|$1@_+'}{@}@_+'+=+++@+#+,+,(#&&#.#>.%$.$.@++=++++++@!@+#++%$&@.@.$.]$$@$]@$&.;%%4%;%%%-$$+++",
|
||||
"++++++&$>.>..*..@-+$+'@={=+{!]=={!^!]!{)!'=++=+@+=+++=+=++++&#.#.#.>...$*.$%$.@+'='@{=+@+!+@@($.@.@&$@.@.@.$.@]@%%<%%%%;%;.(++++",
|
||||
"++++}@,&$%*%*$*.-++===+=+=+_{|]=[!$^@^!+]@'=@++=+++=+'+@++,@#@#$#.#.>.*.$..$%$;-@+'++++!@@@+@($.&@.@.@@@.]@@.@&$;%%4%8%%%.@++++@",
|
||||
"@@+++++#.>.%.%>.+@]++_{='!{+[@^@|]^!^@^|]!++='+@=+'=++=++++@@#.#.#.#.#..>.$.-%----]/'++++7@+@+.$.$&$&@&@@&@@@@@&%;%%%%%;$&(++@@@",
|
||||
"@!@@+@+&..**%*..@++='+=@_+^@='|^!!{^@1@^$+1+@+=+++++=++=@++,@#.#.#.>..>...%.-.-;-)--+++@+@@+,@.@.$.@.$@.@@&@&$&@%;%;%;%.&+(@,+@,",
|
||||
"$]@@@++,.$%..%>.$@++_+|{=]+^+={={==!{!]!{={{=++=+=+'=++++@+@&#$##.#.#.~.>.$.%%$%%)%3;@'+++@++@$.@.$.$.@.@@@&@&@&%4%%%%$(+(@&@,@@",
|
||||
"@$$$@@2@.*.*%*..$@+=+_+=@_@'!{=$={'!^$!]=$_$+'/@=+=++'=++@+,@.#..#.*.>..*.%%$%.;$%;-%-$+{+@++.$.$.@.@.@$&$@&$.@&%%<;%%@(@@@+&@&@",
|
||||
"{$]$@@+@$%.%*.>.@)/'={=+='=+=+[{==!{!{1@1+)=+=+{+'+=@+++@@++#.##.#.#..#..>...$%%;%-;%<)@++@++$$.$.:$.$.$@.@@&$&%;%%%;.@(@&#@#@,@",
|
||||
"+@|$$@(,..>%*%..@@+/=+='=+{='=+={[+=!!]|]!+{$+/=+=++=++@@@#(@#&$*.#.*#.*..%.%.%-%;%;-%--{++++$.$.$@.@$@.$#.@.&$%%%;%%@(@@,@.@&&&",
|
||||
"'@]$$@++...%.%*.$@+=/!+=+=@=+_{==@^{+^!@|{=|)=++{+=+{+}+@@@(,.#.#.*>.*.>.>..-..%$%-;%<;--+@++.@$..:$..$.@.@.#..%%%%%.&,@&@#@,@#@",
|
||||
"++]$$$+&.*%*%*.$$+'=+[='_'$'='_@^{!!!{!]|'=@-+/!+=++=+++#@#2@.#.#.#.~>.*..>..%$%;%;%-;-%)++++$..$..@$@.@$.@&..%%%<%%$&@&#@@&@&&@",
|
||||
"''$]$@++$%.%.%*.$++'=+=+=@!'+=+='=+{!'!1!@={|'+@{=+++++@@@&2&#.#*~.*..#.>.%$..%.%$;%%;-<-)++($.@.$...$@.@.@.$%%%%%%.&&,@&##@#@@@",
|
||||
"++!$$$(+..*%*...@+_@_+[+[@@_{='=+[={!=@^$^@!{+_+++=++++#&#@(#.#..#*#.*.*.>..%$.-.%-;-%)-;3/0@@...@.$@.$@.@..%%%;%%%$&#&#@&@,@@#&",
|
||||
"''])$@(+..%.%*..@'+'+[+=@[++=+=+='+=]=!]|]!@^++=++@++++@#.#,~.*#*..#*#.#..>.$%.%$;%-%;-<--@+@.$..$...@.@$&@%<%%%%%%&&&#&#@,@&@@@",
|
||||
"/+@]$$+($.%*%%*.@@==/='=+]='+'='=+^='!{|=]|$@{++=+++},@#.@(&##..~**..#*.>.>.>.$%.-;%)%--;-)(]..@..@$.$.@.@:%;%4%%%$&#&&#.&#@@@+@",
|
||||
"''!)$]+,..%..*..$++'+=+[+!@_!+_+='!+=@!1$_'[+=]$@=+++@@#.>,&&*#.#.~*#.*#.>.$.%$.-.-;-;-;-<$+&]..$..@.@:@.@.%%%%<%*.&&#&#@,&@,@@@",
|
||||
"++{$$$@($.*%*%.>@'+=+'=+'='+'=+'=+^'^^@^@1+=+++@+@@++&#@.#(##.#*.*$*.#.*#*.*$..%.%%%-;-;-;-(@.$..@.$:$$.@...%%8%%.#.&&#&@@#@@@,@",
|
||||
"_/!]$]@+.>%.%*..$++=++{=++=+=+=+{=+^+^]1+^@'/={++++2+#&#@#+&#.*.#.~.**#*.>.*..$..$;%%-<-%)-:$.@.$..$@.@:@...%.%%%.~#&#&@,@@@+@@@",
|
||||
"+'+$]$+&&.*%*%.>$@+'+=+'={={+=+=+[+^='!^+^@|'++=++++@&#..#&#.#*.*.#*#.*.#*.>.%.%.%.-;%);-<--:@.@&$.$$].$&.....%%%.&#&@,&@,@#@@+@",
|
||||
"_+{$$]@+$..%.*..$@}'++='+=+='='+!'_$!'={[@^@=++/++++#@##@2&#.#*#.*.*.~>~.*..>..$..%$%-%-)%-<@&@&@&@.@$@.$....4%%.#&,&@,@&@@+@@@+",
|
||||
"+/=]$$&&&>%*.%..@@+=+'}=+{=++=+_=@!{!={=={!+'_{+=+++#&$*@(#.#.>.*#.#.*.#.#*...%.%.%.;-;-;-;-.@&+(@@@@@@$...&.%%%.@&@,&@@@@@&@@++",
|
||||
"+'+]$)@+...*%*..@++'=+'='=+[+='+'_+^$|{!]='=++=+/++@#.##2&#.#.*#*.*.*#.**.*.>*.$.$%$%;-%<--<$6@&@&+({(@+&$..%%%..,+&@,@@,@@@@@++",
|
||||
"+++$$).(..%*%.%.@=+++=++='={+=+==+=={|!^@=+^/=+/+++#@#&,(#.#.*#.*#.*#*.#.#*...*.%..%$%;-;-%--&@@@@@++++(+%%.%%%.@(@+@&@@@+@@@+++",
|
||||
"{@{]$]$+&..*%*.&$@_'+'='+=+='=++='=+_{$^!{='=/+=++@#$#&2#.#.>.~*.*.*.#*#*.#.>.>..$%.%-%-;3;-%{&@&@@@@++(,%>.%<.&++,@+@@(@@@@@+@+",
|
||||
"@@@$$;$&@%%.%%.&$+++=+=+='=@=+[/=+='=!_@!{_++[+++@#@~,(,.#.#.*.~*#.**..*.*.*...*..$%.;-;-%-;-$@&@@&@@++(+.%-.>&(+@+@@@@+@@@@@@++",
|
||||
"+{@]$]$&&.*.*%%&@=+=+'='+='='=@='!+=+^@^+='=+/+++@@#(2,~#.#.#*#.*.~.#*~.#*#.#*.$*.$%$.%-;)%-<-6@@@@6@@+@&>%%$&+(+@+@@+@+@@@@{+@+",
|
||||
"@@@$$.]&@.%.%...@++'=+=+=+=++={}+!'!'=@1+=++++}+@(,(#~..~#.*.**~*.**.*>.*.~.*.>..>.%.-;%-;-%--+@&@@@@&@&#.>.&,&+@+@@@@+@@&@@++++",
|
||||
"+@{@)$$&..*%*%..{++=+{='='=^+!@='!+=]={!{='=++++,(#&&#~#.*##.#*.#.#*.*.~.#*.#.**...$%.$;%)%);-:@@@&@@@&@&..,@(@&+@@@@++@@@@@@+++",
|
||||
"+'@@$)$&@..%%%.#++_+=+=+!+=@[+=@={!_+={!@++++/+,@&.#*.*~#..~.#****.~.#*.*..*.*#.>>.%$%%$%)%----+6@@@&@@.##&~@#@+@@@+@+@@]@@++{++",
|
||||
"+++{$-)$..%*.%.@++++'+{='='@={=$=+!'^$_+^+_+++@$&#&~&~*.~#*#*.~.~.*.*.#*.#*#.*.*..>..$;%;-;;-;-+@&@@&$&#&&#&#&@@@@+@+@@.@@@+++++",
|
||||
"++'@)-.$&$.%%%%&+'=+==+=+=={=@={@[@='={!$@+++,@,.&.#*&~~.*&.#*#*#*~.*.*.*..*>.*>.>.%.%$;%)%--;-@&@&@@.@.#&#.#&@@+@+@@@@@@@++++!@",
|
||||
"++++-))$...>.%.@++_++{={'=@_+=+={=]+_@[/^@+@+@#@#.~.~*.~*#*#*.~.*.*.**.*.#*.*#.*.>.$..$;$%);--)$6@&@&#.@*&#.#@,@+@@+@@$@@@++++@@"};
|
|
@ -8,6 +8,10 @@ include *.rst
|
|||
include *.c
|
||||
include *.h
|
||||
include selftest.py tox.ini
|
||||
recursive-include Tests *.py *.txt
|
||||
graft Tests/fonts
|
||||
graft Tests/icc
|
||||
graft Tests/images
|
||||
recursive-include Scripts *.py README
|
||||
graft Images
|
||||
recursive-include docs *.txt *.html *.rst *.css *.py README CHANGES CONTENTS Makefile make.bat
|
||||
|
|
|
@ -18,13 +18,15 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
__version__ = "0.4"
|
||||
|
||||
import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette
|
||||
|
||||
from PngImagePlugin import i16, i32, ChunkStream, _MODES
|
||||
from .PngImagePlugin import i8, i16, i32, ChunkStream, _MODES
|
||||
|
||||
MAGIC = "\212ARG\r\n\032\n"
|
||||
MAGIC = b"\212ARG\r\n\032\n"
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# ARG parser
|
||||
|
@ -60,18 +62,18 @@ class ArgStream(ChunkStream):
|
|||
|
||||
# assertions
|
||||
if self.count != 0:
|
||||
raise SyntaxError, "misplaced AHDR chunk"
|
||||
raise SyntaxError("misplaced AHDR chunk")
|
||||
|
||||
s = self.fp.read(bytes)
|
||||
self.size = i32(s), i32(s[4:])
|
||||
try:
|
||||
self.mode, self.rawmode = _MODES[(ord(s[8]), ord(s[9]))]
|
||||
self.mode, self.rawmode = _MODES[(i8(s[8]), i8(s[9]))]
|
||||
except:
|
||||
raise SyntaxError, "unknown ARG mode"
|
||||
raise SyntaxError("unknown ARG mode")
|
||||
|
||||
if Image.DEBUG:
|
||||
print "AHDR size", self.size
|
||||
print "AHDR mode", self.mode, self.rawmode
|
||||
print("AHDR size", self.size)
|
||||
print("AHDR mode", self.mode, self.rawmode)
|
||||
|
||||
return s
|
||||
|
||||
|
@ -80,7 +82,7 @@ class ArgStream(ChunkStream):
|
|||
|
||||
# assertions
|
||||
if self.count != 0:
|
||||
raise SyntaxError, "misplaced AFRM chunk"
|
||||
raise SyntaxError("misplaced AFRM chunk")
|
||||
|
||||
self.show = 1
|
||||
self.id = 0
|
||||
|
@ -98,7 +100,7 @@ class ArgStream(ChunkStream):
|
|||
self.repair = None
|
||||
|
||||
if Image.DEBUG:
|
||||
print "AFRM", self.id, self.count
|
||||
print("AFRM", self.id, self.count)
|
||||
|
||||
return s
|
||||
|
||||
|
@ -107,7 +109,7 @@ class ArgStream(ChunkStream):
|
|||
|
||||
# assertions
|
||||
if self.count != 0:
|
||||
raise SyntaxError, "misplaced ADEF chunk"
|
||||
raise SyntaxError("misplaced ADEF chunk")
|
||||
|
||||
self.show = 0
|
||||
self.id = 0
|
||||
|
@ -121,7 +123,7 @@ class ArgStream(ChunkStream):
|
|||
self.count = i16(s[2:4])
|
||||
|
||||
if Image.DEBUG:
|
||||
print "ADEF", self.id, self.count
|
||||
print("ADEF", self.id, self.count)
|
||||
|
||||
return s
|
||||
|
||||
|
@ -130,7 +132,7 @@ class ArgStream(ChunkStream):
|
|||
|
||||
# assertions
|
||||
if self.count == 0:
|
||||
raise SyntaxError, "misplaced NAME chunk"
|
||||
raise SyntaxError("misplaced NAME chunk")
|
||||
|
||||
name = self.fp.read(bytes)
|
||||
self.names[self.id] = name
|
||||
|
@ -141,26 +143,26 @@ class ArgStream(ChunkStream):
|
|||
"AEND -- end of animation"
|
||||
|
||||
if Image.DEBUG:
|
||||
print "AEND"
|
||||
print("AEND")
|
||||
|
||||
self.eof = 1
|
||||
|
||||
raise EOFError, "end of ARG file"
|
||||
raise EOFError("end of ARG file")
|
||||
|
||||
def __getmodesize(self, s, full=1):
|
||||
|
||||
size = i32(s), i32(s[4:])
|
||||
|
||||
try:
|
||||
mode, rawmode = _MODES[(ord(s[8]), ord(s[9]))]
|
||||
mode, rawmode = _MODES[(i8(s[8]), i8(s[9]))]
|
||||
except:
|
||||
raise SyntaxError, "unknown image mode"
|
||||
raise SyntaxError("unknown image mode")
|
||||
|
||||
if full:
|
||||
if ord(s[12]):
|
||||
if i8(s[12]):
|
||||
pass # interlace not yet supported
|
||||
if ord(s[11]):
|
||||
raise SyntaxError, "unknown filter category"
|
||||
if i8(s[11]):
|
||||
raise SyntaxError("unknown filter category")
|
||||
|
||||
return size, mode, rawmode
|
||||
|
||||
|
@ -169,7 +171,7 @@ class ArgStream(ChunkStream):
|
|||
|
||||
# assertions
|
||||
if self.count == 0:
|
||||
raise SyntaxError, "misplaced PAST chunk"
|
||||
raise SyntaxError("misplaced PAST chunk")
|
||||
|
||||
if self.repair is not None:
|
||||
# we must repair the target image before we
|
||||
|
@ -206,7 +208,7 @@ class ArgStream(ChunkStream):
|
|||
|
||||
# assertions
|
||||
if self.count == 0:
|
||||
raise SyntaxError, "misplaced BLNK chunk"
|
||||
raise SyntaxError("misplaced BLNK chunk")
|
||||
|
||||
s = self.fp.read(bytes)
|
||||
size, mode, rawmode = self.__getmodesize(s, 0)
|
||||
|
@ -223,7 +225,7 @@ class ArgStream(ChunkStream):
|
|||
|
||||
# assertions
|
||||
if self.count == 0:
|
||||
raise SyntaxError, "misplaced IHDR chunk"
|
||||
raise SyntaxError("misplaced IHDR chunk")
|
||||
|
||||
# image header
|
||||
s = self.fp.read(bytes)
|
||||
|
@ -234,7 +236,7 @@ class ArgStream(ChunkStream):
|
|||
self.im = Image.core.new(mode, size)
|
||||
self.decoder = Image.core.zip_decoder(rawmode)
|
||||
self.decoder.setimage(self.im, (0,0) + size)
|
||||
self.data = ""
|
||||
self.data = b""
|
||||
|
||||
return s
|
||||
|
||||
|
@ -243,20 +245,20 @@ class ArgStream(ChunkStream):
|
|||
|
||||
# assertions
|
||||
if self.count == 0:
|
||||
raise SyntaxError, "misplaced DHDR chunk"
|
||||
raise SyntaxError("misplaced DHDR chunk")
|
||||
|
||||
s = self.fp.read(bytes)
|
||||
|
||||
size, mode, rawmode = self.__getmodesize(s)
|
||||
|
||||
# delta header
|
||||
diff = ord(s[13])
|
||||
diff = i8(s[13])
|
||||
offs = i32(s[14:18]), i32(s[18:22])
|
||||
|
||||
bbox = offs + (offs[0]+size[0], offs[1]+size[1])
|
||||
|
||||
if Image.DEBUG:
|
||||
print "DHDR", diff, bbox
|
||||
print("DHDR", diff, bbox)
|
||||
|
||||
# FIXME: decode and apply image
|
||||
self.action = ("DHDR", diff, bbox)
|
||||
|
@ -267,7 +269,7 @@ class ArgStream(ChunkStream):
|
|||
self.decoder = Image.core.zip_decoder(rawmode)
|
||||
self.decoder.setimage(self.im, (0,0) + size)
|
||||
|
||||
self.data = ""
|
||||
self.data = b""
|
||||
|
||||
return s
|
||||
|
||||
|
@ -276,7 +278,7 @@ class ArgStream(ChunkStream):
|
|||
|
||||
# assertions
|
||||
if self.count == 0:
|
||||
raise SyntaxError, "misplaced JHDR chunk"
|
||||
raise SyntaxError("misplaced JHDR chunk")
|
||||
|
||||
# image header
|
||||
s = self.fp.read(bytes)
|
||||
|
@ -287,7 +289,7 @@ class ArgStream(ChunkStream):
|
|||
self.im = Image.core.new(mode, size)
|
||||
self.decoder = Image.core.jpeg_decoder(rawmode)
|
||||
self.decoder.setimage(self.im, (0,0) + size)
|
||||
self.data = ""
|
||||
self.data = b""
|
||||
|
||||
return s
|
||||
|
||||
|
@ -296,7 +298,7 @@ class ArgStream(ChunkStream):
|
|||
|
||||
# assertions
|
||||
if self.count == 0:
|
||||
raise SyntaxError, "misplaced UHDR chunk"
|
||||
raise SyntaxError("misplaced UHDR chunk")
|
||||
|
||||
# image header
|
||||
s = self.fp.read(bytes)
|
||||
|
@ -307,7 +309,7 @@ class ArgStream(ChunkStream):
|
|||
self.im = Image.core.new(mode, size)
|
||||
self.decoder = Image.core.raw_decoder(rawmode)
|
||||
self.decoder.setimage(self.im, (0,0) + size)
|
||||
self.data = ""
|
||||
self.data = b""
|
||||
|
||||
return s
|
||||
|
||||
|
@ -321,7 +323,7 @@ class ArgStream(ChunkStream):
|
|||
if n < 0:
|
||||
# end of image
|
||||
if e < 0:
|
||||
raise IOError, "decoder error %d" % e
|
||||
raise IOError("decoder error %d" % e)
|
||||
else:
|
||||
self.data = self.data[n:]
|
||||
|
||||
|
@ -386,7 +388,7 @@ class ArgStream(ChunkStream):
|
|||
"SYNC -- reset decoder"
|
||||
|
||||
if self.count != 0:
|
||||
raise SyntaxError, "misplaced sYNC chunk"
|
||||
raise SyntaxError("misplaced sYNC chunk")
|
||||
|
||||
s = self.fp.read(bytes)
|
||||
self.__reset()
|
||||
|
@ -418,7 +420,7 @@ class ArgImageFile(ImageFile.ImageFile):
|
|||
)
|
||||
|
||||
if self.fp.read(8) != MAGIC:
|
||||
raise SyntaxError, "not an ARG file"
|
||||
raise SyntaxError("not an ARG file")
|
||||
|
||||
self.arg = ArgStream(self.fp)
|
||||
|
||||
|
@ -427,7 +429,7 @@ class ArgImageFile(ImageFile.ImageFile):
|
|||
cid, offset, bytes = self.arg.read()
|
||||
|
||||
if cid != "AHDR":
|
||||
raise SyntaxError, "expected an AHDR chunk"
|
||||
raise SyntaxError("expected an AHDR chunk")
|
||||
|
||||
s = self.arg.call(cid, offset, bytes)
|
||||
|
||||
|
@ -452,11 +454,11 @@ class ArgImageFile(ImageFile.ImageFile):
|
|||
def seek(self, frame):
|
||||
|
||||
if self.arg.eof:
|
||||
raise EOFError, "end of animation"
|
||||
raise EOFError("end of animation")
|
||||
|
||||
self.fp = self.arg.fp
|
||||
|
||||
while 1:
|
||||
while True:
|
||||
|
||||
#
|
||||
# process chunks
|
||||
|
@ -464,7 +466,7 @@ class ArgImageFile(ImageFile.ImageFile):
|
|||
cid, offset, bytes = self.arg.read()
|
||||
|
||||
if self.arg.eof:
|
||||
raise EOFError, "end of animation"
|
||||
raise EOFError("end of animation")
|
||||
|
||||
try:
|
||||
s = self.arg.call(cid, offset, bytes)
|
||||
|
@ -473,7 +475,7 @@ class ArgImageFile(ImageFile.ImageFile):
|
|||
|
||||
except "glurk": # AttributeError
|
||||
if Image.DEBUG:
|
||||
print cid, bytes, "(unknown)"
|
||||
print(cid, bytes, "(unknown)")
|
||||
s = self.fp.read(bytes)
|
||||
|
||||
self.arg.crc(cid, s)
|
||||
|
|
|
@ -17,10 +17,9 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
import FontFile
|
||||
from . import Image
|
||||
from . import FontFile
|
||||
|
||||
import string
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# parse X Bitmap Distribution Format (BDF)
|
||||
|
@ -44,39 +43,39 @@ bdf_spacing = {
|
|||
def bdf_char(f):
|
||||
|
||||
# skip to STARTCHAR
|
||||
while 1:
|
||||
while True:
|
||||
s = f.readline()
|
||||
if not s:
|
||||
return None
|
||||
if s[:9] == "STARTCHAR":
|
||||
if s[:9] == b"STARTCHAR":
|
||||
break
|
||||
id = string.strip(s[9:])
|
||||
id = s[9:].strip().decode('ascii')
|
||||
|
||||
# load symbol properties
|
||||
props = {}
|
||||
while 1:
|
||||
while True:
|
||||
s = f.readline()
|
||||
if not s or s[:6] == "BITMAP":
|
||||
if not s or s[:6] == b"BITMAP":
|
||||
break
|
||||
i = string.find(s, " ")
|
||||
props[s[:i]] = s[i+1:-1]
|
||||
i = s.find(b" ")
|
||||
props[s[:i].decode('ascii')] = s[i+1:-1].decode('ascii')
|
||||
|
||||
# load bitmap
|
||||
bitmap = []
|
||||
while 1:
|
||||
while True:
|
||||
s = f.readline()
|
||||
if not s or s[:7] == "ENDCHAR":
|
||||
if not s or s[:7] == b"ENDCHAR":
|
||||
break
|
||||
bitmap.append(s[:-1])
|
||||
bitmap = string.join(bitmap, "")
|
||||
bitmap = b"".join(bitmap)
|
||||
|
||||
[x, y, l, d] = map(int, string.split(props["BBX"]))
|
||||
[dx, dy] = map(int, string.split(props["DWIDTH"]))
|
||||
[x, y, l, d] = [int(s) for s in props["BBX"].split()]
|
||||
[dx, dy] = [int(s) for s in props["DWIDTH"].split()]
|
||||
|
||||
bbox = (dx, dy), (l, -d-y, x+l, -d), (0, 0, x, y)
|
||||
|
||||
try:
|
||||
im = Image.fromstring("1", (x, y), bitmap, "hex", "1")
|
||||
im = Image.frombytes("1", (x, y), bitmap, "hex", "1")
|
||||
except ValueError:
|
||||
# deal with zero-width characters
|
||||
im = Image.new("1", (x, y))
|
||||
|
@ -93,38 +92,38 @@ class BdfFontFile(FontFile.FontFile):
|
|||
FontFile.FontFile.__init__(self)
|
||||
|
||||
s = fp.readline()
|
||||
if s[:13] != "STARTFONT 2.1":
|
||||
raise SyntaxError, "not a valid BDF file"
|
||||
if s[:13] != b"STARTFONT 2.1":
|
||||
raise SyntaxError("not a valid BDF file")
|
||||
|
||||
props = {}
|
||||
comments = []
|
||||
|
||||
while 1:
|
||||
while True:
|
||||
s = fp.readline()
|
||||
if not s or s[:13] == "ENDPROPERTIES":
|
||||
if not s or s[:13] == b"ENDPROPERTIES":
|
||||
break
|
||||
i = string.find(s, " ")
|
||||
props[s[:i]] = s[i+1:-1]
|
||||
if s[:i] in ["COMMENT", "COPYRIGHT"]:
|
||||
if string.find(s, "LogicalFontDescription") < 0:
|
||||
comments.append(s[i+1:-1])
|
||||
i = s.find(b" ")
|
||||
props[s[:i].decode('ascii')] = s[i+1:-1].decode('ascii')
|
||||
if s[:i] in [b"COMMENT", b"COPYRIGHT"]:
|
||||
if s.find(b"LogicalFontDescription") < 0:
|
||||
comments.append(s[i+1:-1].decode('ascii'))
|
||||
|
||||
font = string.split(props["FONT"], "-")
|
||||
font = props["FONT"].split("-")
|
||||
|
||||
font[4] = bdf_slant[string.upper(font[4])]
|
||||
font[11] = bdf_spacing[string.upper(font[11])]
|
||||
font[4] = bdf_slant[font[4].upper()]
|
||||
font[11] = bdf_spacing[font[11].upper()]
|
||||
|
||||
ascent = int(props["FONT_ASCENT"])
|
||||
descent = int(props["FONT_DESCENT"])
|
||||
|
||||
fontname = string.join(font[1:], ";")
|
||||
fontname = ";".join(font[1:])
|
||||
|
||||
# print "#", fontname
|
||||
# for i in comments:
|
||||
# print "#", i
|
||||
|
||||
font = []
|
||||
while 1:
|
||||
while True:
|
||||
c = bdf_char(fp)
|
||||
if not c:
|
||||
break
|
||||
|
|
|
@ -27,21 +27,19 @@
|
|||
__version__ = "0.7"
|
||||
|
||||
|
||||
import string
|
||||
import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16le
|
||||
i32 = _binary.i32le
|
||||
o8 = _binary.o8
|
||||
o16 = _binary.o16le
|
||||
o32 = _binary.o32le
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# Read BMP file
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
|
||||
|
||||
BIT2MODE = {
|
||||
# bits => mode, rawmode
|
||||
1: ("P", "P;1"),
|
||||
|
@ -53,7 +51,7 @@ BIT2MODE = {
|
|||
}
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:2] == "BM"
|
||||
return prefix[:2] == b"BM"
|
||||
|
||||
##
|
||||
# Image plugin for the Windows BMP format.
|
||||
|
@ -93,7 +91,7 @@ class BmpImageFile(ImageFile.ImageFile):
|
|||
lutsize = 4
|
||||
colors = i32(s[32:])
|
||||
direction = -1
|
||||
if s[11] == '\xff':
|
||||
if i8(s[11]) == 0xff:
|
||||
# upside-down storage
|
||||
self.size = self.size[0], 2**32 - self.size[1]
|
||||
direction = 0
|
||||
|
@ -132,10 +130,10 @@ class BmpImageFile(ImageFile.ImageFile):
|
|||
if colors == 2:
|
||||
indices = (0, 255)
|
||||
else:
|
||||
indices = range(colors)
|
||||
indices = list(range(colors))
|
||||
for i in indices:
|
||||
rgb = read(lutsize)[:3]
|
||||
if rgb != chr(i)*3:
|
||||
if rgb != o8(i)*3:
|
||||
greyscale = 0
|
||||
palette.append(rgb)
|
||||
if greyscale:
|
||||
|
@ -146,7 +144,7 @@ class BmpImageFile(ImageFile.ImageFile):
|
|||
else:
|
||||
self.mode = "P"
|
||||
self.palette = ImagePalette.raw(
|
||||
"BGR", string.join(palette, "")
|
||||
"BGR", b"".join(palette)
|
||||
)
|
||||
|
||||
if not offset:
|
||||
|
@ -163,7 +161,7 @@ class BmpImageFile(ImageFile.ImageFile):
|
|||
|
||||
# HEAD
|
||||
s = self.fp.read(14)
|
||||
if s[:2] != "BM":
|
||||
if s[:2] != b"BM":
|
||||
raise SyntaxError("Not a BMP file")
|
||||
offset = i32(s[10:])
|
||||
|
||||
|
@ -182,12 +180,6 @@ class DibImageFile(BmpImageFile):
|
|||
# --------------------------------------------------------------------
|
||||
# Write BMP file
|
||||
|
||||
def o16(i):
|
||||
return chr(i&255) + chr(i>>8&255)
|
||||
|
||||
def o32(i):
|
||||
return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255)
|
||||
|
||||
SAVE = {
|
||||
"1": ("1", 1, 2),
|
||||
"L": ("L", 8, 256),
|
||||
|
@ -205,13 +197,13 @@ def _save(im, fp, filename, check=0):
|
|||
if check:
|
||||
return check
|
||||
|
||||
stride = ((im.size[0]*bits+7)/8+3)&(~3)
|
||||
stride = ((im.size[0]*bits+7)//8+3)&(~3)
|
||||
header = 40 # or 64 for OS/2 version 2
|
||||
offset = 14 + header + colors * 4
|
||||
image = stride * im.size[1]
|
||||
|
||||
# bitmap header
|
||||
fp.write("BM" + # file type (magic)
|
||||
fp.write(b"BM" + # file type (magic)
|
||||
o32(offset+image) + # file size
|
||||
o32(0) + # reserved
|
||||
o32(offset)) # image data offset
|
||||
|
@ -228,14 +220,14 @@ def _save(im, fp, filename, check=0):
|
|||
o32(colors) + # colors used
|
||||
o32(colors)) # colors important
|
||||
|
||||
fp.write("\000" * (header - 40)) # padding (for OS/2 format)
|
||||
fp.write(b"\0" * (header - 40)) # padding (for OS/2 format)
|
||||
|
||||
if im.mode == "1":
|
||||
for i in (0, 255):
|
||||
fp.write(chr(i) * 4)
|
||||
fp.write(o8(i) * 4)
|
||||
elif im.mode == "L":
|
||||
for i in range(256):
|
||||
fp.write(chr(i) * 4)
|
||||
fp.write(o8(i) * 4)
|
||||
elif im.mode == "P":
|
||||
fp.write(im.im.getpalette("RGB", "BGRX"))
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile
|
||||
|
||||
_handler = None
|
||||
|
||||
|
@ -26,7 +26,7 @@ def register_handler(handler):
|
|||
# Image adapter
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] == "BUFR" or prefix[:4] == "ZCZC"
|
||||
return prefix[:4] == b"BUFR" or prefix[:4] == b"ZCZC"
|
||||
|
||||
class BufrStubImageFile(ImageFile.StubImageFile):
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ class ContainerIO:
|
|||
|
||||
def readline(self):
|
||||
s = ""
|
||||
while 1:
|
||||
while True:
|
||||
c = self.read(1)
|
||||
if not c:
|
||||
break
|
||||
|
@ -108,7 +108,7 @@ class ContainerIO:
|
|||
|
||||
def readlines(self):
|
||||
l = []
|
||||
while 1:
|
||||
while True:
|
||||
s = self.readline()
|
||||
if not s:
|
||||
break
|
||||
|
|
|
@ -19,21 +19,19 @@
|
|||
|
||||
__version__ = "0.1"
|
||||
|
||||
import Image, BmpImagePlugin
|
||||
from . import Image, BmpImagePlugin, _binary
|
||||
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16le
|
||||
i32 = _binary.i32le
|
||||
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] == "\0\0\2\0"
|
||||
return prefix[:4] == b"\0\0\2\0"
|
||||
|
||||
##
|
||||
# Image plugin for Windows Cursor files.
|
||||
|
@ -50,20 +48,20 @@ class CurImageFile(BmpImagePlugin.BmpImageFile):
|
|||
# check magic
|
||||
s = self.fp.read(6)
|
||||
if not _accept(s):
|
||||
raise SyntaxError, "not an CUR file"
|
||||
raise SyntaxError("not an CUR file")
|
||||
|
||||
# pick the largest cursor in the file
|
||||
m = ""
|
||||
m = b""
|
||||
for i in range(i16(s[4:])):
|
||||
s = self.fp.read(16)
|
||||
if not m:
|
||||
m = s
|
||||
elif ord(s[0]) > ord(m[0]) and ord(s[1]) > ord(m[1]):
|
||||
elif i8(s[0]) > i8(m[0]) and i8(s[1]) > i8(m[1]):
|
||||
m = s
|
||||
#print "width", ord(s[0])
|
||||
#print "height", ord(s[1])
|
||||
#print "colors", ord(s[2])
|
||||
#print "reserved", ord(s[3])
|
||||
#print "width", i8(s[0])
|
||||
#print "height", i8(s[1])
|
||||
#print "colors", i8(s[2])
|
||||
#print "reserved", i8(s[3])
|
||||
#print "hotspot x", i16(s[4:])
|
||||
#print "hotspot y", i16(s[6:])
|
||||
#print "bytes", i32(s[8:])
|
||||
|
@ -73,7 +71,7 @@ class CurImageFile(BmpImagePlugin.BmpImageFile):
|
|||
self._bitmap(i32(m[12:]) + offset)
|
||||
|
||||
# patch up the bitmap height
|
||||
self.size = self.size[0], self.size[1]/2
|
||||
self.size = self.size[0], self.size[1]//2
|
||||
d, e, o, a = self.tile[0]
|
||||
self.tile[0] = d, (0,0)+self.size, o, a
|
||||
|
||||
|
|
|
@ -23,14 +23,13 @@
|
|||
|
||||
__version__ = "0.2"
|
||||
|
||||
import Image
|
||||
from . import Image, _binary
|
||||
|
||||
from PcxImagePlugin import PcxImageFile
|
||||
from .PcxImagePlugin import PcxImageFile
|
||||
|
||||
MAGIC = 0x3ADE68B1 # QUIZ: what's this value, then?
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
i32 = _binary.i32le
|
||||
|
||||
def _accept(prefix):
|
||||
return i32(prefix) == MAGIC
|
||||
|
@ -48,7 +47,7 @@ class DcxImageFile(PcxImageFile):
|
|||
# Header
|
||||
s = self.fp.read(4)
|
||||
if i32(s) != MAGIC:
|
||||
raise SyntaxError, "not a DCX file"
|
||||
raise SyntaxError("not a DCX file")
|
||||
|
||||
# Component directory
|
||||
self._offset = []
|
||||
|
|
|
@ -20,17 +20,15 @@
|
|||
|
||||
__version__ = "0.5"
|
||||
|
||||
import re, string
|
||||
import Image, ImageFile
|
||||
import re
|
||||
import io
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
|
||||
def o32(i):
|
||||
return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255)
|
||||
i32 = _binary.i32le
|
||||
o32 = _binary.o32le
|
||||
|
||||
split = re.compile(r"^%%([^:]*):[ \t]*(.*)[ \t]*$")
|
||||
field = re.compile(r"^%[%!\w]([^:]*)[ \t]*$")
|
||||
|
@ -55,7 +53,7 @@ def Ghostscript(tile, size, fp):
|
|||
"-sOutputFile=%s" % file,# output file
|
||||
"- >/dev/null 2>/dev/null"]
|
||||
|
||||
command = string.join(command)
|
||||
command = " ".join(command)
|
||||
|
||||
# push data through ghostscript
|
||||
try:
|
||||
|
@ -93,30 +91,32 @@ class PSFile:
|
|||
def seek(self, offset, whence=0):
|
||||
self.char = None
|
||||
self.fp.seek(offset, whence)
|
||||
def read(self, count):
|
||||
return self.fp.read(count).decode('latin-1')
|
||||
def tell(self):
|
||||
pos = self.fp.tell()
|
||||
if self.char:
|
||||
pos = pos - 1
|
||||
return pos
|
||||
def readline(self):
|
||||
s = ""
|
||||
s = b""
|
||||
if self.char:
|
||||
c = self.char
|
||||
self.char = None
|
||||
else:
|
||||
c = self.fp.read(1)
|
||||
while c not in "\r\n":
|
||||
while c not in b"\r\n":
|
||||
s = s + c
|
||||
c = self.fp.read(1)
|
||||
if c == "\r":
|
||||
if c == b"\r":
|
||||
self.char = self.fp.read(1)
|
||||
if self.char == "\n":
|
||||
if self.char == b"\n":
|
||||
self.char = None
|
||||
return s + "\n"
|
||||
return s.decode('latin-1') + "\n"
|
||||
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] == "%!PS" or i32(prefix) == 0xC6D3D0C5L
|
||||
return prefix[:4] == b"%!PS" or i32(prefix) == 0xC6D3D0C5
|
||||
|
||||
##
|
||||
# Image plugin for Encapsulated Postscript. This plugin supports only
|
||||
|
@ -141,12 +141,12 @@ class EpsImageFile(ImageFile.ImageFile):
|
|||
offset = 0
|
||||
fp.seek(0, 2)
|
||||
length = fp.tell()
|
||||
elif i32(s) == 0xC6D3D0C5L:
|
||||
elif i32(s) == 0xC6D3D0C5:
|
||||
offset = i32(s[4:])
|
||||
length = i32(s[8:])
|
||||
fp.seek(offset)
|
||||
else:
|
||||
raise SyntaxError, "not an EPS file"
|
||||
raise SyntaxError("not an EPS file")
|
||||
|
||||
fp.seek(offset)
|
||||
|
||||
|
@ -163,7 +163,7 @@ class EpsImageFile(ImageFile.ImageFile):
|
|||
while s:
|
||||
|
||||
if len(s) > 255:
|
||||
raise SyntaxError, "not an EPS file"
|
||||
raise SyntaxError("not an EPS file")
|
||||
|
||||
if s[-2:] == '\r\n':
|
||||
s = s[:-2]
|
||||
|
@ -172,8 +172,8 @@ class EpsImageFile(ImageFile.ImageFile):
|
|||
|
||||
try:
|
||||
m = split.match(s)
|
||||
except re.error, v:
|
||||
raise SyntaxError, "not an EPS file"
|
||||
except re.error as v:
|
||||
raise SyntaxError("not an EPS file")
|
||||
|
||||
if m:
|
||||
k, v = m.group(1, 2)
|
||||
|
@ -183,7 +183,7 @@ class EpsImageFile(ImageFile.ImageFile):
|
|||
# Note: The DSC spec says that BoundingBox
|
||||
# fields should be integers, but some drivers
|
||||
# put floating point values there anyway.
|
||||
box = map(int, map(float, string.split(v)))
|
||||
box = [int(float(s)) for s in v.split()]
|
||||
self.size = box[2] - box[0], box[3] - box[1]
|
||||
self.tile = [("eps", (0,0) + self.size, offset,
|
||||
(length, box))]
|
||||
|
@ -196,18 +196,19 @@ class EpsImageFile(ImageFile.ImageFile):
|
|||
|
||||
if m:
|
||||
k = m.group(1)
|
||||
|
||||
if k == "EndComments":
|
||||
break
|
||||
if k[:8] == "PS-Adobe":
|
||||
self.info[k[:8]] = k[9:]
|
||||
else:
|
||||
self.info[k] = ""
|
||||
elif s[0] == '%':
|
||||
elif s[0:1] == '%':
|
||||
# handle non-DSC Postscript comments that some
|
||||
# tools mistakenly put in the Comments section
|
||||
pass
|
||||
else:
|
||||
raise IOError, "bad EPS header"
|
||||
raise IOError("bad EPS header")
|
||||
|
||||
s = fp.readline()
|
||||
|
||||
|
@ -221,7 +222,7 @@ class EpsImageFile(ImageFile.ImageFile):
|
|||
while s[0] == "%":
|
||||
|
||||
if len(s) > 255:
|
||||
raise SyntaxError, "not an EPS file"
|
||||
raise SyntaxError("not an EPS file")
|
||||
|
||||
if s[-2:] == '\r\n':
|
||||
s = s[:-2]
|
||||
|
@ -231,7 +232,7 @@ class EpsImageFile(ImageFile.ImageFile):
|
|||
if s[:11] == "%ImageData:":
|
||||
|
||||
[x, y, bi, mo, z3, z4, en, id] =\
|
||||
string.split(s[11:], maxsplit=7)
|
||||
s[11:].split(None, 7)
|
||||
|
||||
x = int(x); y = int(y)
|
||||
|
||||
|
@ -261,7 +262,7 @@ class EpsImageFile(ImageFile.ImageFile):
|
|||
id = id[1:-1]
|
||||
|
||||
# Scan forward to the actual image data
|
||||
while 1:
|
||||
while True:
|
||||
s = fp.readline()
|
||||
if not s:
|
||||
break
|
||||
|
@ -278,7 +279,7 @@ class EpsImageFile(ImageFile.ImageFile):
|
|||
break
|
||||
|
||||
if not box:
|
||||
raise IOError, "cannot determine EPS bounding box"
|
||||
raise IOError("cannot determine EPS bounding box")
|
||||
|
||||
def load(self):
|
||||
# Load EPS via Ghostscript
|
||||
|
@ -308,7 +309,18 @@ def _save(im, fp, filename, eps=1):
|
|||
elif im.mode == "CMYK":
|
||||
operator = (8, 4, "false 4 colorimage")
|
||||
else:
|
||||
raise ValueError, "image mode is not supported"
|
||||
raise ValueError("image mode is not supported")
|
||||
|
||||
class NoCloseStream:
|
||||
def __init__(self, fp):
|
||||
self.fp = fp
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.fp, name)
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
base_fp = fp
|
||||
fp = io.TextIOWrapper(NoCloseStream(fp), encoding='latin-1')
|
||||
|
||||
if eps:
|
||||
#
|
||||
|
@ -332,9 +344,10 @@ def _save(im, fp, filename, eps=1):
|
|||
fp.write("%d %d 8\n" % im.size) # <= bits
|
||||
fp.write("[%d 0 0 -%d 0 %d]\n" % (im.size[0], im.size[1], im.size[1]))
|
||||
fp.write("{ currentfile buf readhexstring pop } bind\n")
|
||||
fp.write("%s\n" % operator[2])
|
||||
fp.write(operator[2] + "\n")
|
||||
fp.flush()
|
||||
|
||||
ImageFile._save(im, fp, [("eps", (0,0)+im.size, 0, None)])
|
||||
ImageFile._save(im, base_fp, [("eps", (0,0)+im.size, 0, None)])
|
||||
|
||||
fp.write("\n%%%%EndBinary\n")
|
||||
fp.write("grestore end\n")
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile
|
||||
|
||||
_handler = None
|
||||
|
||||
|
@ -26,7 +26,7 @@ def register_handler(handler):
|
|||
# Image adapter
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:6] == "SIMPLE"
|
||||
return prefix[:6] == b"SIMPLE"
|
||||
|
||||
class FITSStubImageFile(ImageFile.StubImageFile):
|
||||
|
||||
|
|
|
@ -18,15 +18,12 @@
|
|||
|
||||
__version__ = "0.2"
|
||||
|
||||
import Image, ImageFile, ImagePalette
|
||||
import string
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16le
|
||||
i32 = _binary.i32le
|
||||
o8 = _binary.o8
|
||||
|
||||
#
|
||||
# decoder
|
||||
|
@ -51,7 +48,7 @@ class FliImageFile(ImageFile.ImageFile):
|
|||
if not (magic in [0xAF11, 0xAF12] and
|
||||
i16(s[14:16]) in [0, 3] and # flags
|
||||
s[20:22] == '\x00\x00'): # reserved
|
||||
raise SyntaxError, "not an FLI/FLC file"
|
||||
raise SyntaxError("not an FLI/FLC file")
|
||||
|
||||
# image characteristics
|
||||
self.mode = "P"
|
||||
|
@ -64,7 +61,7 @@ class FliImageFile(ImageFile.ImageFile):
|
|||
self.info["duration"] = duration
|
||||
|
||||
# look for palette
|
||||
palette = map(lambda a: (a,a,a), range(256))
|
||||
palette = [(a,a,a) for a in range(256)]
|
||||
|
||||
s = self.fp.read(16)
|
||||
|
||||
|
@ -83,8 +80,8 @@ class FliImageFile(ImageFile.ImageFile):
|
|||
elif i16(s[4:6]) == 4:
|
||||
self._palette(palette, 0)
|
||||
|
||||
palette = map(lambda (r,g,b): chr(r)+chr(g)+chr(b), palette)
|
||||
self.palette = ImagePalette.raw("RGB", string.join(palette, ""))
|
||||
palette = [o8(r)+o8(g)+o8(b) for (r,g,b) in palette]
|
||||
self.palette = ImagePalette.raw("RGB", b"".join(palette))
|
||||
|
||||
# set things up to decode first frame
|
||||
self.frame = -1
|
||||
|
@ -98,22 +95,22 @@ class FliImageFile(ImageFile.ImageFile):
|
|||
i = 0
|
||||
for e in range(i16(self.fp.read(2))):
|
||||
s = self.fp.read(2)
|
||||
i = i + ord(s[0])
|
||||
n = ord(s[1])
|
||||
i = i + i8(s[0])
|
||||
n = i8(s[1])
|
||||
if n == 0:
|
||||
n = 256
|
||||
s = self.fp.read(n * 3)
|
||||
for n in range(0, len(s), 3):
|
||||
r = ord(s[n]) << shift
|
||||
g = ord(s[n+1]) << shift
|
||||
b = ord(s[n+2]) << shift
|
||||
r = i8(s[n]) << shift
|
||||
g = i8(s[n+1]) << shift
|
||||
b = i8(s[n+2]) << shift
|
||||
palette[i] = (r, g, b)
|
||||
i = i + 1
|
||||
|
||||
def seek(self, frame):
|
||||
|
||||
if frame != self.frame + 1:
|
||||
raise ValueError, "cannot seek to frame %d" % frame
|
||||
raise ValueError("cannot seek to frame %d" % frame)
|
||||
self.frame = frame
|
||||
|
||||
# move to next frame
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#
|
||||
|
||||
import os
|
||||
import Image
|
||||
from . import Image, _binary
|
||||
|
||||
import marshal
|
||||
|
||||
|
@ -31,7 +31,7 @@ def puti16(fp, values):
|
|||
for v in values:
|
||||
if v < 0:
|
||||
v = v + 65536
|
||||
fp.write(chr(v>>8&255) + chr(v&255))
|
||||
fp.write(_binary.o16be(v))
|
||||
|
||||
##
|
||||
# Base class for raster font file handlers.
|
||||
|
@ -106,9 +106,9 @@ class FontFile:
|
|||
|
||||
# font metrics
|
||||
fp = open(os.path.splitext(filename)[0] + ".pil", "wb")
|
||||
fp.write("PILfont\n")
|
||||
fp.write(";;;;;;%d;\n" % self.ysize) # HACK!!!
|
||||
fp.write("DATA\n")
|
||||
fp.write(b"PILfont\n")
|
||||
fp.write((";;;;;;%d;\n" % self.ysize).encode('ascii')) # HACK!!!
|
||||
fp.write(b"DATA\n")
|
||||
for id in range(256):
|
||||
m = self.metrics[id]
|
||||
if not m:
|
||||
|
@ -128,13 +128,13 @@ class FontFile:
|
|||
data = marshal.dumps((self.metrics, self.info))
|
||||
|
||||
if zlib:
|
||||
data = "z" + zlib.compress(data, 9)
|
||||
data = b"z" + zlib.compress(data, 9)
|
||||
else:
|
||||
data = "u" + data
|
||||
data = b"u" + data
|
||||
|
||||
fp = open(os.path.splitext(filename)[0] + ".pil", "wb")
|
||||
|
||||
fp.write("PILfont2\n" + self.name + "\n" + "DATA\n")
|
||||
fp.write(b"PILfont2\n" + self.name + "\n" + "DATA\n")
|
||||
|
||||
fp.write(data)
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
__version__ = "0.1"
|
||||
|
||||
|
||||
import Image, ImageFile
|
||||
from OleFileIO import *
|
||||
from . import Image, ImageFile
|
||||
from .OleFileIO import *
|
||||
|
||||
|
||||
# we map from colour field tuples to (mode, rawmode) descriptors
|
||||
|
@ -60,10 +60,10 @@ class FpxImageFile(ImageFile.ImageFile):
|
|||
try:
|
||||
self.ole = OleFileIO(self.fp)
|
||||
except IOError:
|
||||
raise SyntaxError, "not an FPX file; invalid OLE file"
|
||||
raise SyntaxError("not an FPX file; invalid OLE file")
|
||||
|
||||
if self.ole.root.clsid != "56616700-C154-11CE-8553-00AA00A1F95B":
|
||||
raise SyntaxError, "not an FPX file; bad root CLSID"
|
||||
raise SyntaxError("not an FPX file; bad root CLSID")
|
||||
|
||||
self._open_index(1)
|
||||
|
||||
|
@ -108,7 +108,7 @@ class FpxImageFile(ImageFile.ImageFile):
|
|||
self.jpeg = {}
|
||||
for i in range(256):
|
||||
id = 0x3000001|(i << 16)
|
||||
if prop.has_key(id):
|
||||
if id in prop:
|
||||
self.jpeg[i] = prop[id]
|
||||
|
||||
# print len(self.jpeg), "tables loaded"
|
||||
|
@ -143,7 +143,7 @@ class FpxImageFile(ImageFile.ImageFile):
|
|||
# print size, self.mode, self.rawmode
|
||||
|
||||
if size != self.size:
|
||||
raise IOError, "subimage mismatch"
|
||||
raise IOError("subimage mismatch")
|
||||
|
||||
# get tile descriptors
|
||||
fp.seek(28 + offset)
|
||||
|
@ -170,8 +170,8 @@ class FpxImageFile(ImageFile.ImageFile):
|
|||
|
||||
elif compression == 2:
|
||||
|
||||
internal_color_conversion = ord(s[14])
|
||||
jpeg_tables = ord(s[15])
|
||||
internal_color_conversion = i8(s[14])
|
||||
jpeg_tables = i8(s[15])
|
||||
rawmode = self.rawmode
|
||||
|
||||
if internal_color_conversion:
|
||||
|
@ -198,7 +198,7 @@ class FpxImageFile(ImageFile.ImageFile):
|
|||
self.tile_prefix = self.jpeg[jpeg_tables]
|
||||
|
||||
else:
|
||||
raise IOError, "unknown/invalid compression"
|
||||
raise IOError("unknown/invalid compression")
|
||||
|
||||
x = x + xtile
|
||||
if x >= xsize:
|
||||
|
|
|
@ -13,10 +13,9 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
def i32(c):
|
||||
return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24L)
|
||||
i32 = _binary.i32be
|
||||
|
||||
def _accept(prefix):
|
||||
return i32(prefix) >= 20 and i32(prefix[4:8]) == 1
|
||||
|
@ -34,13 +33,13 @@ class GbrImageFile(ImageFile.ImageFile):
|
|||
header_size = i32(self.fp.read(4))
|
||||
version = i32(self.fp.read(4))
|
||||
if header_size < 20 or version != 1:
|
||||
raise SyntaxError, "not a GIMP brush"
|
||||
raise SyntaxError("not a GIMP brush")
|
||||
|
||||
width = i32(self.fp.read(4))
|
||||
height = i32(self.fp.read(4))
|
||||
bytes = i32(self.fp.read(4))
|
||||
if width <= 0 or height <= 0 or bytes != 1:
|
||||
raise SyntaxError, "not a GIMP brush"
|
||||
raise SyntaxError("not a GIMP brush")
|
||||
|
||||
comment = self.fp.read(header_size - 20)[:-1]
|
||||
|
||||
|
@ -59,8 +58,8 @@ class GbrImageFile(ImageFile.ImageFile):
|
|||
|
||||
# create an image out of the brush data block
|
||||
self.im = Image.core.new(self.mode, self.size)
|
||||
self.im.fromstring(self.data)
|
||||
self.data = ""
|
||||
self.im.frombytes(self.data)
|
||||
self.data = b""
|
||||
|
||||
#
|
||||
# registry
|
||||
|
|
|
@ -25,10 +25,15 @@
|
|||
|
||||
__version__ = "0.1"
|
||||
|
||||
import ImageFile, ImagePalette
|
||||
from . import ImageFile, ImagePalette, _binary
|
||||
|
||||
def i16(c):
|
||||
return ord(c[1]) + (ord(c[0])<<8)
|
||||
try:
|
||||
import builtins
|
||||
except ImportError:
|
||||
import __builtin__
|
||||
builtins = __builtin__
|
||||
|
||||
i16 = _binary.i16be
|
||||
|
||||
##
|
||||
# Image plugin for the GD uncompressed format. Note that this format
|
||||
|
@ -72,10 +77,9 @@ def open(fp, mode = "r"):
|
|||
if mode != "r":
|
||||
raise ValueError("bad mode")
|
||||
|
||||
if type(fp) == type(""):
|
||||
import __builtin__
|
||||
if isinstance(fp, str):
|
||||
filename = fp
|
||||
fp = __builtin__.open(fp, "rb")
|
||||
fp = builtins.open(fp, "rb")
|
||||
else:
|
||||
filename = ""
|
||||
|
||||
|
|
|
@ -28,24 +28,23 @@
|
|||
__version__ = "0.9"
|
||||
|
||||
|
||||
import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Helpers
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def o16(i):
|
||||
return chr(i&255) + chr(i>>8&255)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16le
|
||||
o8 = _binary.o8
|
||||
o16 = _binary.o16le
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Identify/read GIF files
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:6] in ["GIF87a", "GIF89a"]
|
||||
return prefix[:6] in [b"GIF87a", b"GIF89a"]
|
||||
|
||||
##
|
||||
# Image plugin for GIF images. This plugin supports both GIF87 and
|
||||
|
@ -60,16 +59,16 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
|
||||
def data(self):
|
||||
s = self.fp.read(1)
|
||||
if s and ord(s):
|
||||
return self.fp.read(ord(s))
|
||||
if s and i8(s):
|
||||
return self.fp.read(i8(s))
|
||||
return None
|
||||
|
||||
def _open(self):
|
||||
|
||||
# Screen
|
||||
s = self.fp.read(13)
|
||||
if s[:6] not in ["GIF87a", "GIF89a"]:
|
||||
raise SyntaxError, "not a GIF file"
|
||||
if s[:6] not in [b"GIF87a", b"GIF89a"]:
|
||||
raise SyntaxError("not a GIF file")
|
||||
|
||||
self.info["version"] = s[:6]
|
||||
|
||||
|
@ -77,17 +76,17 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
|
||||
self.tile = []
|
||||
|
||||
flags = ord(s[10])
|
||||
flags = i8(s[10])
|
||||
|
||||
bits = (flags & 7) + 1
|
||||
|
||||
if flags & 128:
|
||||
# get global palette
|
||||
self.info["background"] = ord(s[11])
|
||||
self.info["background"] = i8(s[11])
|
||||
# check if palette contains colour indices
|
||||
p = self.fp.read(3<<bits)
|
||||
for i in range(0, len(p), 3):
|
||||
if not (chr(i/3) == p[i] == p[i+1] == p[i+2]):
|
||||
if not (i//3 == i8(p[i]) == i8(p[i+1]) == i8(p[i+2])):
|
||||
p = ImagePalette.raw("RGB", p)
|
||||
self.global_palette = self.palette = p
|
||||
break
|
||||
|
@ -106,7 +105,7 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
self.__fp.seek(self.__rewind)
|
||||
|
||||
if frame != self.__frame + 1:
|
||||
raise ValueError, "cannot seek to frame %d" % frame
|
||||
raise ValueError("cannot seek to frame %d" % frame)
|
||||
self.__frame = frame
|
||||
|
||||
self.tile = []
|
||||
|
@ -125,25 +124,25 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
|
||||
self.palette = self.global_palette
|
||||
|
||||
while 1:
|
||||
while True:
|
||||
|
||||
s = self.fp.read(1)
|
||||
if not s or s == ";":
|
||||
if not s or s == b";":
|
||||
break
|
||||
|
||||
elif s == "!":
|
||||
elif s == b"!":
|
||||
#
|
||||
# extensions
|
||||
#
|
||||
s = self.fp.read(1)
|
||||
block = self.data()
|
||||
if ord(s) == 249:
|
||||
if i8(s) == 249:
|
||||
#
|
||||
# graphic control extension
|
||||
#
|
||||
flags = ord(block[0])
|
||||
flags = i8(block[0])
|
||||
if flags & 1:
|
||||
self.info["transparency"] = ord(block[3])
|
||||
self.info["transparency"] = i8(block[3])
|
||||
self.info["duration"] = i16(block[1:3]) * 10
|
||||
try:
|
||||
# disposal methods
|
||||
|
@ -156,19 +155,19 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
self.dispose = self.im.copy()
|
||||
except (AttributeError, KeyError):
|
||||
pass
|
||||
elif ord(s) == 255:
|
||||
elif i8(s) == 255:
|
||||
#
|
||||
# application extension
|
||||
#
|
||||
self.info["extension"] = block, self.fp.tell()
|
||||
if block[:11] == "NETSCAPE2.0":
|
||||
if block[:11] == b"NETSCAPE2.0":
|
||||
block = self.data()
|
||||
if len(block) >= 3 and ord(block[0]) == 1:
|
||||
if len(block) >= 3 and i8(block[0]) == 1:
|
||||
self.info["loop"] = i16(block[1:3])
|
||||
while self.data():
|
||||
pass
|
||||
|
||||
elif s == ",":
|
||||
elif s == b",":
|
||||
#
|
||||
# local image
|
||||
#
|
||||
|
@ -177,7 +176,7 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
# extent
|
||||
x0, y0 = i16(s[0:]), i16(s[2:])
|
||||
x1, y1 = x0 + i16(s[4:]), y0 + i16(s[6:])
|
||||
flags = ord(s[8])
|
||||
flags = i8(s[8])
|
||||
|
||||
interlace = (flags & 64) != 0
|
||||
|
||||
|
@ -187,7 +186,7 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
ImagePalette.raw("RGB", self.fp.read(3<<bits))
|
||||
|
||||
# image data
|
||||
bits = ord(self.fp.read(1))
|
||||
bits = i8(self.fp.read(1))
|
||||
self.__offset = self.fp.tell()
|
||||
self.tile = [("gif",
|
||||
(x0, y0, x1, y1),
|
||||
|
@ -197,11 +196,11 @@ class GifImageFile(ImageFile.ImageFile):
|
|||
|
||||
else:
|
||||
pass
|
||||
# raise IOError, "illegal GIF tag `%x`" % ord(s)
|
||||
# raise IOError, "illegal GIF tag `%x`" % i8(s)
|
||||
|
||||
if not self.tile:
|
||||
# self.__fp = None
|
||||
raise EOFError, "no more images in GIF file"
|
||||
raise EOFError("no more images in GIF file")
|
||||
|
||||
self.mode = "L"
|
||||
if self.palette:
|
||||
|
@ -272,29 +271,29 @@ def _save(im, fp, filename):
|
|||
pass
|
||||
else:
|
||||
# transparency extension block
|
||||
fp.write("!" +
|
||||
chr(249) + # extension intro
|
||||
chr(4) + # length
|
||||
chr(1) + # transparency info present
|
||||
fp.write(b"!" +
|
||||
o8(249) + # extension intro
|
||||
o8(4) + # length
|
||||
o8(1) + # transparency info present
|
||||
o16(0) + # duration
|
||||
chr(int(transparency)) # transparency index
|
||||
+ chr(0))
|
||||
o8(int(transparency)) # transparency index
|
||||
+ o8(0))
|
||||
|
||||
# local image header
|
||||
fp.write("," +
|
||||
fp.write(b"," +
|
||||
o16(0) + o16(0) + # bounding box
|
||||
o16(im.size[0]) + # size
|
||||
o16(im.size[1]) +
|
||||
chr(flags) + # flags
|
||||
chr(8)) # bits
|
||||
o8(flags) + # flags
|
||||
o8(8)) # bits
|
||||
|
||||
imOut.encoderconfig = (8, interlace)
|
||||
|
||||
ImageFile._save(imOut, fp, [("gif", (0,0)+im.size, 0, rawmode)])
|
||||
|
||||
fp.write("\0") # end of image data
|
||||
fp.write(b"\0") # end of image data
|
||||
|
||||
fp.write(";") # end of file
|
||||
fp.write(b";") # end of file
|
||||
|
||||
try:
|
||||
fp.flush()
|
||||
|
@ -326,12 +325,12 @@ def getheader(im, info=None):
|
|||
optimize = info and info.get("optimize", 0)
|
||||
|
||||
s = [
|
||||
"GIF87a" + # magic
|
||||
b"GIF87a" + # magic
|
||||
o16(im.size[0]) + # size
|
||||
o16(im.size[1]) +
|
||||
chr(7 + 128) + # flags: bits + palette
|
||||
chr(0) + # background
|
||||
chr(0) # reserved/aspect
|
||||
o8(7 + 128) + # flags: bits + palette
|
||||
o8(0) + # background
|
||||
o8(0) # reserved/aspect
|
||||
]
|
||||
|
||||
if optimize:
|
||||
|
@ -352,7 +351,7 @@ def getheader(im, info=None):
|
|||
else:
|
||||
# greyscale
|
||||
for i in range(maxcolor):
|
||||
s.append(chr(i) * 3)
|
||||
s.append(o8(i) * 3)
|
||||
|
||||
return s
|
||||
|
||||
|
@ -374,17 +373,17 @@ def getdata(im, offset = (0, 0), **params):
|
|||
im.encoderinfo = params
|
||||
|
||||
# local image header
|
||||
fp.write("," +
|
||||
fp.write(b"," +
|
||||
o16(offset[0]) + # offset
|
||||
o16(offset[1]) +
|
||||
o16(im.size[0]) + # size
|
||||
o16(im.size[1]) +
|
||||
chr(0) + # flags
|
||||
chr(8)) # bits
|
||||
o8(0) + # flags
|
||||
o8(8)) # bits
|
||||
|
||||
ImageFile._save(im, fp, [("gif", (0,0)+im.size, 0, RAWMODE[im.mode])])
|
||||
|
||||
fp.write("\0") # end of image data
|
||||
fp.write(b"\0") # end of image data
|
||||
|
||||
finally:
|
||||
del im.encoderinfo
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#
|
||||
|
||||
from math import pi, log, sin, sqrt
|
||||
import string
|
||||
from ._binary import o8
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Stuff to translate curve segments to palette values (derived from
|
||||
|
@ -79,15 +79,15 @@ class GradientFile:
|
|||
scale = segment((xm - x0) / w, (x - x0) / w)
|
||||
|
||||
# expand to RGBA
|
||||
r = chr(int(255 * ((rgb1[0] - rgb0[0]) * scale + rgb0[0]) + 0.5))
|
||||
g = chr(int(255 * ((rgb1[1] - rgb0[1]) * scale + rgb0[1]) + 0.5))
|
||||
b = chr(int(255 * ((rgb1[2] - rgb0[2]) * scale + rgb0[2]) + 0.5))
|
||||
a = chr(int(255 * ((rgb1[3] - rgb0[3]) * scale + rgb0[3]) + 0.5))
|
||||
r = o8(int(255 * ((rgb1[0] - rgb0[0]) * scale + rgb0[0]) + 0.5))
|
||||
g = o8(int(255 * ((rgb1[1] - rgb0[1]) * scale + rgb0[1]) + 0.5))
|
||||
b = o8(int(255 * ((rgb1[2] - rgb0[2]) * scale + rgb0[2]) + 0.5))
|
||||
a = o8(int(255 * ((rgb1[3] - rgb0[3]) * scale + rgb0[3]) + 0.5))
|
||||
|
||||
# add to palette
|
||||
palette.append(r + g + b + a)
|
||||
|
||||
return string.join(palette, ""), "RGBA"
|
||||
return b"".join(palette), "RGBA"
|
||||
|
||||
##
|
||||
# File handler for GIMP's gradient format.
|
||||
|
@ -96,8 +96,8 @@ class GimpGradientFile(GradientFile):
|
|||
|
||||
def __init__(self, fp):
|
||||
|
||||
if fp.readline()[:13] != "GIMP Gradient":
|
||||
raise SyntaxError, "not a GIMP gradient file"
|
||||
if fp.readline()[:13] != b"GIMP Gradient":
|
||||
raise SyntaxError("not a GIMP gradient file")
|
||||
|
||||
count = int(fp.readline())
|
||||
|
||||
|
@ -105,8 +105,8 @@ class GimpGradientFile(GradientFile):
|
|||
|
||||
for i in range(count):
|
||||
|
||||
s = string.split(fp.readline())
|
||||
w = map(float, s[:11])
|
||||
s = fp.readline().split()
|
||||
w = [float(x) for x in s[:11]]
|
||||
|
||||
x0, x1 = w[0], w[2]
|
||||
xm = w[1]
|
||||
|
@ -117,7 +117,7 @@ class GimpGradientFile(GradientFile):
|
|||
cspace = int(s[12])
|
||||
|
||||
if cspace != 0:
|
||||
raise IOError, "cannot handle HSV colour space"
|
||||
raise IOError("cannot handle HSV colour space")
|
||||
|
||||
gradient.append((x0, x1, xm, rgb0, rgb1, segment))
|
||||
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import re, string
|
||||
import re
|
||||
from ._binary import o8
|
||||
|
||||
##
|
||||
# File handler for GIMP's palette format.
|
||||
|
@ -25,10 +26,10 @@ class GimpPaletteFile:
|
|||
|
||||
def __init__(self, fp):
|
||||
|
||||
self.palette = map(lambda i: chr(i)*3, range(256))
|
||||
self.palette = [o8(i)*3 for i in range(256)]
|
||||
|
||||
if fp.readline()[:12] != "GIMP Palette":
|
||||
raise SyntaxError, "not a GIMP palette file"
|
||||
if fp.readline()[:12] != b"GIMP Palette":
|
||||
raise SyntaxError("not a GIMP palette file")
|
||||
|
||||
i = 0
|
||||
|
||||
|
@ -39,21 +40,21 @@ class GimpPaletteFile:
|
|||
if not s:
|
||||
break
|
||||
# skip fields and comment lines
|
||||
if re.match("\w+:|#", s):
|
||||
if re.match(b"\w+:|#", s):
|
||||
continue
|
||||
if len(s) > 100:
|
||||
raise SyntaxError, "bad palette file"
|
||||
raise SyntaxError("bad palette file")
|
||||
|
||||
v = tuple(map(int, string.split(s)[:3]))
|
||||
v = tuple(map(int, s.split()[:3]))
|
||||
if len(v) != 3:
|
||||
raise ValueError, "bad palette entry"
|
||||
raise ValueError("bad palette entry")
|
||||
|
||||
if 0 <= i <= 255:
|
||||
self.palette[i] = chr(v[0]) + chr(v[1]) + chr(v[2])
|
||||
self.palette[i] = o8(v[0]) + o8(v[1]) + o8(v[2])
|
||||
|
||||
i = i + 1
|
||||
|
||||
self.palette = string.join(self.palette, "")
|
||||
self.palette = b"".join(self.palette)
|
||||
|
||||
|
||||
def getpalette(self):
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile
|
||||
|
||||
_handler = None
|
||||
|
||||
|
@ -26,7 +26,7 @@ def register_handler(handler):
|
|||
# Image adapter
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[0:4] == "GRIB" and prefix[7] == chr(1)
|
||||
return prefix[0:4] == b"GRIB" and prefix[7] == b'\x01'
|
||||
|
||||
class GribStubImageFile(ImageFile.StubImageFile):
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile
|
||||
|
||||
_handler = None
|
||||
|
||||
|
@ -26,7 +26,7 @@ def register_handler(handler):
|
|||
# Image adapter
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:8] == "\x89HDF\r\n\x1a\n"
|
||||
return prefix[:8] == b"\x89HDF\r\n\x1a\n"
|
||||
|
||||
class HDF5StubImageFile(ImageFile.StubImageFile):
|
||||
|
||||
|
|
|
@ -14,27 +14,31 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageFile
|
||||
import string, struct
|
||||
from . import Image, ImageFile, _binary
|
||||
import struct
|
||||
|
||||
i8 = _binary.i8
|
||||
|
||||
HEADERSIZE = 8
|
||||
|
||||
def nextheader(fobj):
|
||||
return struct.unpack('>4sI', fobj.read(HEADERSIZE))
|
||||
|
||||
def read_32t(fobj, (start, length), (width, height)):
|
||||
def read_32t(fobj, start_length, size):
|
||||
# The 128x128 icon seems to have an extra header for some reason.
|
||||
(start, length) = start_length
|
||||
fobj.seek(start)
|
||||
sig = fobj.read(4)
|
||||
if sig != '\x00\x00\x00\x00':
|
||||
raise SyntaxError, 'Unknown signature, expecting 0x00000000'
|
||||
return read_32(fobj, (start + 4, length - 4), (width, height))
|
||||
if sig != b'\x00\x00\x00\x00':
|
||||
raise SyntaxError('Unknown signature, expecting 0x00000000')
|
||||
return read_32(fobj, (start + 4, length - 4), size)
|
||||
|
||||
def read_32(fobj, (start, length), size):
|
||||
def read_32(fobj, start_length, size):
|
||||
"""
|
||||
Read a 32bit RGB icon resource. Seems to be either uncompressed or
|
||||
an RLE packbits-like scheme.
|
||||
"""
|
||||
(start, length) = start_length
|
||||
fobj.seek(start)
|
||||
sizesq = size[0] * size[1]
|
||||
if length == sizesq * 3:
|
||||
|
@ -51,7 +55,7 @@ def read_32(fobj, (start, length), size):
|
|||
byte = fobj.read(1)
|
||||
if not byte:
|
||||
break
|
||||
byte = ord(byte)
|
||||
byte = i8(byte)
|
||||
if byte & 0x80:
|
||||
blocksize = byte - 125
|
||||
byte = fobj.read(1)
|
||||
|
@ -68,13 +72,14 @@ def read_32(fobj, (start, length), size):
|
|||
"Error reading channel [%r left]" % bytesleft
|
||||
)
|
||||
band = Image.frombuffer(
|
||||
"L", size, string.join(data, ""), "raw", "L", 0, 1
|
||||
"L", size, b"".join(data), "raw", "L", 0, 1
|
||||
)
|
||||
im.im.putband(band.im, band_ix)
|
||||
return {"RGB": im}
|
||||
|
||||
def read_mk(fobj, (start, length), size):
|
||||
def read_mk(fobj, start_length, size):
|
||||
# Alpha masks seem to be uncompressed
|
||||
(start, length) = start_length
|
||||
fobj.seek(start)
|
||||
band = Image.frombuffer(
|
||||
"L", size, fobj.read(size[0]*size[1]), "raw", "L", 0, 1
|
||||
|
@ -85,20 +90,20 @@ class IcnsFile:
|
|||
|
||||
SIZES = {
|
||||
(128, 128): [
|
||||
('it32', read_32t),
|
||||
('t8mk', read_mk),
|
||||
(b'it32', read_32t),
|
||||
(b't8mk', read_mk),
|
||||
],
|
||||
(48, 48): [
|
||||
('ih32', read_32),
|
||||
('h8mk', read_mk),
|
||||
(b'ih32', read_32),
|
||||
(b'h8mk', read_mk),
|
||||
],
|
||||
(32, 32): [
|
||||
('il32', read_32),
|
||||
('l8mk', read_mk),
|
||||
(b'il32', read_32),
|
||||
(b'l8mk', read_mk),
|
||||
],
|
||||
(16, 16): [
|
||||
('is32', read_32),
|
||||
('s8mk', read_mk),
|
||||
(b'is32', read_32),
|
||||
(b's8mk', read_mk),
|
||||
],
|
||||
}
|
||||
|
||||
|
@ -111,7 +116,7 @@ class IcnsFile:
|
|||
self.fobj = fobj
|
||||
sig, filesize = nextheader(fobj)
|
||||
if sig != 'icns':
|
||||
raise SyntaxError, 'not an icns file'
|
||||
raise SyntaxError('not an icns file')
|
||||
i = HEADERSIZE
|
||||
while i < filesize:
|
||||
sig, blocksize = nextheader(fobj)
|
||||
|
@ -125,7 +130,7 @@ class IcnsFile:
|
|||
sizes = []
|
||||
for size, fmts in self.SIZES.items():
|
||||
for (fmt, reader) in fmts:
|
||||
if self.dct.has_key(fmt):
|
||||
if fmt in self.dct:
|
||||
sizes.append(size)
|
||||
break
|
||||
return sizes
|
||||
|
@ -133,7 +138,7 @@ class IcnsFile:
|
|||
def bestsize(self):
|
||||
sizes = self.itersizes()
|
||||
if not sizes:
|
||||
raise SyntaxError, "No 32bit icon resources found"
|
||||
raise SyntaxError("No 32bit icon resources found")
|
||||
return max(sizes)
|
||||
|
||||
def dataforsize(self, size):
|
||||
|
@ -201,7 +206,7 @@ class IcnsImageFile(ImageFile.ImageFile):
|
|||
self.load_end()
|
||||
|
||||
|
||||
Image.register_open("ICNS", IcnsImageFile, lambda x: x[:4] == 'icns')
|
||||
Image.register_open("ICNS", IcnsImageFile, lambda x: x[:4] == b'icns')
|
||||
Image.register_extension("ICNS", '.icns')
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -19,21 +19,19 @@
|
|||
|
||||
__version__ = "0.1"
|
||||
|
||||
import Image, BmpImagePlugin
|
||||
from . import Image, BmpImagePlugin, _binary
|
||||
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16le
|
||||
i32 = _binary.i32le
|
||||
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] == "\0\0\1\0"
|
||||
return prefix[:4] == b"\0\0\1\0"
|
||||
|
||||
##
|
||||
# Image plugin for Windows Icon files.
|
||||
|
@ -48,20 +46,20 @@ class IcoImageFile(BmpImagePlugin.BmpImageFile):
|
|||
# check magic
|
||||
s = self.fp.read(6)
|
||||
if not _accept(s):
|
||||
raise SyntaxError, "not an ICO file"
|
||||
raise SyntaxError("not an ICO file")
|
||||
|
||||
# pick the largest icon in the file
|
||||
m = ""
|
||||
m = b""
|
||||
for i in range(i16(s[4:])):
|
||||
s = self.fp.read(16)
|
||||
if not m:
|
||||
m = s
|
||||
elif ord(s[0]) > ord(m[0]) and ord(s[1]) > ord(m[1]):
|
||||
elif i8(s[0]) > i8(m[0]) and i8(s[1]) > i8(m[1]):
|
||||
m = s
|
||||
#print "width", ord(s[0])
|
||||
#print "height", ord(s[1])
|
||||
#print "colors", ord(s[2])
|
||||
#print "reserved", ord(s[3])
|
||||
#print "width", i8(s[0])
|
||||
#print "height", i8(s[1])
|
||||
#print "colors", i8(s[2])
|
||||
#print "reserved", i8(s[3])
|
||||
#print "planes", i16(s[4:])
|
||||
#print "bitcount", i16(s[6:])
|
||||
#print "bytes", i32(s[8:])
|
||||
|
@ -71,7 +69,7 @@ class IcoImageFile(BmpImagePlugin.BmpImageFile):
|
|||
self._bitmap(i32(m[12:]))
|
||||
|
||||
# patch up the bitmap height
|
||||
self.size = self.size[0], self.size[1]/2
|
||||
self.size = self.size[0], self.size[1]//2
|
||||
d, e, o, a = self.tile[0]
|
||||
self.tile[0] = d, (0,0)+self.size, o, a
|
||||
|
||||
|
|
|
@ -28,8 +28,9 @@
|
|||
|
||||
__version__ = "0.7"
|
||||
|
||||
import re, string
|
||||
import Image, ImageFile, ImagePalette
|
||||
import re
|
||||
from . import Image, ImageFile, ImagePalette
|
||||
from ._binary import i8, o8
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -91,7 +92,7 @@ for i in range(2, 33):
|
|||
# --------------------------------------------------------------------
|
||||
# Read IM directory
|
||||
|
||||
split = re.compile(r"^([A-Za-z][^:]*):[ \t]*(.*)[ \t]*$")
|
||||
split = re.compile(br"^([A-Za-z][^:]*):[ \t]*(.*)[ \t]*$")
|
||||
|
||||
def number(s):
|
||||
try:
|
||||
|
@ -112,8 +113,8 @@ class ImImageFile(ImageFile.ImageFile):
|
|||
# Quick rejection: if there's not an LF among the first
|
||||
# 100 bytes, this is (probably) not a text header.
|
||||
|
||||
if not "\n" in self.fp.read(100):
|
||||
raise SyntaxError, "not an IM file"
|
||||
if not b"\n" in self.fp.read(100):
|
||||
raise SyntaxError("not an IM file")
|
||||
self.fp.seek(0)
|
||||
|
||||
n = 0
|
||||
|
@ -125,91 +126,96 @@ class ImImageFile(ImageFile.ImageFile):
|
|||
|
||||
self.rawmode = "L"
|
||||
|
||||
while 1:
|
||||
while True:
|
||||
|
||||
s = self.fp.read(1)
|
||||
|
||||
# Some versions of IFUNC uses \n\r instead of \r\n...
|
||||
if s == "\r":
|
||||
if s == b"\r":
|
||||
continue
|
||||
|
||||
if not s or s[0] == chr(0) or s[0] == chr(26):
|
||||
if not s or s == b'\0' or s == b'\x1A':
|
||||
break
|
||||
|
||||
# FIXME: this may read whole file if not a text file
|
||||
s = s + self.fp.readline()
|
||||
|
||||
if len(s) > 100:
|
||||
raise SyntaxError, "not an IM file"
|
||||
raise SyntaxError("not an IM file")
|
||||
|
||||
if s[-2:] == '\r\n':
|
||||
if s[-2:] == b'\r\n':
|
||||
s = s[:-2]
|
||||
elif s[-1:] == '\n':
|
||||
elif s[-1:] == b'\n':
|
||||
s = s[:-1]
|
||||
|
||||
try:
|
||||
m = split.match(s)
|
||||
except re.error, v:
|
||||
raise SyntaxError, "not an IM file"
|
||||
except re.error as v:
|
||||
raise SyntaxError("not an IM file")
|
||||
|
||||
if m:
|
||||
|
||||
k, v = m.group(1,2)
|
||||
|
||||
# Don't know if this is the correct encoding, but a decent guess
|
||||
# (I guess)
|
||||
k = k.decode('latin-1', 'replace')
|
||||
v = v.decode('latin-1', 'replace')
|
||||
|
||||
# Convert value as appropriate
|
||||
if k in [FRAMES, SCALE, SIZE]:
|
||||
v = string.replace(v, "*", ",")
|
||||
v = tuple(map(number, string.split(v, ",")))
|
||||
v = v.replace("*", ",")
|
||||
v = tuple(map(number, v.split(",")))
|
||||
if len(v) == 1:
|
||||
v = v[0]
|
||||
elif k == MODE and OPEN.has_key(v):
|
||||
elif k == MODE and v in OPEN:
|
||||
v, self.rawmode = OPEN[v]
|
||||
|
||||
# Add to dictionary. Note that COMMENT tags are
|
||||
# combined into a list of strings.
|
||||
if k == COMMENT:
|
||||
if self.info.has_key(k):
|
||||
if k in self.info:
|
||||
self.info[k].append(v)
|
||||
else:
|
||||
self.info[k] = [v]
|
||||
else:
|
||||
self.info[k] = v
|
||||
|
||||
if TAGS.has_key(k):
|
||||
if k in TAGS:
|
||||
n = n + 1
|
||||
|
||||
else:
|
||||
|
||||
raise SyntaxError, "Syntax error in IM header: " + s
|
||||
raise SyntaxError("Syntax error in IM header: " + s.decode('ascii', 'replace'))
|
||||
|
||||
if not n:
|
||||
raise SyntaxError, "Not an IM file"
|
||||
raise SyntaxError("Not an IM file")
|
||||
|
||||
# Basic attributes
|
||||
self.size = self.info[SIZE]
|
||||
self.mode = self.info[MODE]
|
||||
|
||||
# Skip forward to start of image data
|
||||
while s and s[0] != chr(26):
|
||||
while s and s[0:1] != b'\x1A':
|
||||
s = self.fp.read(1)
|
||||
if not s:
|
||||
raise SyntaxError, "File truncated"
|
||||
raise SyntaxError("File truncated")
|
||||
|
||||
if self.info.has_key(LUT):
|
||||
if LUT in self.info:
|
||||
# convert lookup table to palette or lut attribute
|
||||
palette = self.fp.read(768)
|
||||
greyscale = 1 # greyscale palette
|
||||
linear = 1 # linear greyscale palette
|
||||
for i in range(256):
|
||||
if palette[i] == palette[i+256] == palette[i+512]:
|
||||
if palette[i] != chr(i):
|
||||
if i8(palette[i]) != i:
|
||||
linear = 0
|
||||
else:
|
||||
greyscale = 0
|
||||
if self.mode == "L" or self.mode == "LA":
|
||||
if greyscale:
|
||||
if not linear:
|
||||
self.lut = map(ord, palette[:256])
|
||||
self.lut = [i8(c) for c in palette[:256]]
|
||||
else:
|
||||
if self.mode == "L":
|
||||
self.mode = self.rawmode = "P"
|
||||
|
@ -218,7 +224,7 @@ class ImImageFile(ImageFile.ImageFile):
|
|||
self.palette = ImagePalette.raw("RGB;L", palette)
|
||||
elif self.mode == "RGB":
|
||||
if not greyscale or not linear:
|
||||
self.lut = map(ord, palette)
|
||||
self.lut = [i8(c) for c in palette]
|
||||
|
||||
self.frame = 0
|
||||
|
||||
|
@ -253,7 +259,7 @@ class ImImageFile(ImageFile.ImageFile):
|
|||
def seek(self, frame):
|
||||
|
||||
if frame < 0 or frame >= self.info[FRAMES]:
|
||||
raise EOFError, "seek outside sequence"
|
||||
raise EOFError("seek outside sequence")
|
||||
|
||||
if self.frame == frame:
|
||||
return
|
||||
|
@ -265,7 +271,7 @@ class ImImageFile(ImageFile.ImageFile):
|
|||
else:
|
||||
bits = 8 * len(self.mode)
|
||||
|
||||
size = ((self.size[0] * bits + 7) / 8) * self.size[1]
|
||||
size = ((self.size[0] * bits + 7) // 8) * self.size[1]
|
||||
offs = self.__offset + frame * size
|
||||
|
||||
self.fp = self.__fp
|
||||
|
@ -304,7 +310,7 @@ def _save(im, fp, filename, check=0):
|
|||
try:
|
||||
type, rawmode = SAVE[im.mode]
|
||||
except KeyError:
|
||||
raise ValueError, "Cannot save %s images as IM" % im.mode
|
||||
raise ValueError("Cannot save %s images as IM" % im.mode)
|
||||
|
||||
try:
|
||||
frames = im.encoderinfo["frames"]
|
||||
|
@ -314,14 +320,14 @@ def _save(im, fp, filename, check=0):
|
|||
if check:
|
||||
return check
|
||||
|
||||
fp.write("Image type: %s image\r\n" % type)
|
||||
fp.write(("Image type: %s image\r\n" % type).encode('ascii'))
|
||||
if filename:
|
||||
fp.write("Name: %s\r\n" % filename)
|
||||
fp.write("Image size (x*y): %d*%d\r\n" % im.size)
|
||||
fp.write("File size (no of images): %d\r\n" % frames)
|
||||
fp.write(("Name: %s\r\n" % filename).encode('ascii'))
|
||||
fp.write(("Image size (x*y): %d*%d\r\n" % im.size).encode('ascii'))
|
||||
fp.write(("File size (no of images): %d\r\n" % frames).encode('ascii'))
|
||||
if im.mode == "P":
|
||||
fp.write("Lut: 1\r\n")
|
||||
fp.write("\000" * (511-fp.tell()) + "\032")
|
||||
fp.write(b"Lut: 1\r\n")
|
||||
fp.write(b"\000" * (511-fp.tell()) + b"\032")
|
||||
if im.mode == "P":
|
||||
fp.write(im.im.getpalette("RGB", "RGB;L")) # 768 bytes
|
||||
ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, -1))])
|
||||
|
|
264
PIL/Image.py
264
PIL/Image.py
|
@ -24,6 +24,8 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
VERSION = "1.1.7"
|
||||
|
||||
try:
|
||||
|
@ -52,7 +54,7 @@ try:
|
|||
# them. Note that other modules should not refer to _imaging
|
||||
# directly; import Image and use the Image.core variable instead.
|
||||
import _imaging as core
|
||||
except ImportError, v:
|
||||
except ImportError as v:
|
||||
core = _imaging_not_installed()
|
||||
if str(v)[:20] == "Module use of python" and warnings:
|
||||
# The _imaging C module is present, but not compiled for
|
||||
|
@ -64,31 +66,27 @@ except ImportError, v:
|
|||
RuntimeWarning
|
||||
)
|
||||
|
||||
import ImageMode
|
||||
import ImagePalette
|
||||
try:
|
||||
import builtins
|
||||
except ImportError:
|
||||
import __builtin__
|
||||
builtins = __builtin__
|
||||
|
||||
import os, string, sys
|
||||
from . import ImageMode
|
||||
from ._binary import i8, o8
|
||||
|
||||
import os, sys
|
||||
|
||||
# type stuff
|
||||
from types import IntType, StringType, TupleType
|
||||
import collections
|
||||
import numbers
|
||||
|
||||
try:
|
||||
UnicodeStringType = type(unicode(""))
|
||||
##
|
||||
# (Internal) Checks if an object is a string. If the current
|
||||
# Python version supports Unicode, this checks for both 8-bit
|
||||
# and Unicode strings.
|
||||
if bytes is str:
|
||||
def isStringType(t):
|
||||
return isinstance(t, StringType) or isinstance(t, UnicodeStringType)
|
||||
except NameError:
|
||||
return isinstance(t, basestring)
|
||||
else:
|
||||
def isStringType(t):
|
||||
return isinstance(t, StringType)
|
||||
|
||||
##
|
||||
# (Internal) Checks if an object is a tuple.
|
||||
|
||||
def isTupleType(t):
|
||||
return isinstance(t, TupleType)
|
||||
return isinstance(t, str)
|
||||
|
||||
##
|
||||
# (Internal) Checks if an object is an image object.
|
||||
|
@ -103,8 +101,6 @@ def isImageType(t):
|
|||
def isDirectory(f):
|
||||
return isStringType(f) and os.path.isdir(f)
|
||||
|
||||
from operator import isNumberType, isSequenceType
|
||||
|
||||
#
|
||||
# Debug level
|
||||
|
||||
|
@ -186,16 +182,7 @@ _MODEINFO = {
|
|||
|
||||
}
|
||||
|
||||
try:
|
||||
byteorder = sys.byteorder
|
||||
except AttributeError:
|
||||
import struct
|
||||
if struct.unpack("h", "\0\1")[0] == 1:
|
||||
byteorder = "big"
|
||||
else:
|
||||
byteorder = "little"
|
||||
|
||||
if byteorder == 'little':
|
||||
if sys.byteorder == 'little':
|
||||
_ENDIAN = '<'
|
||||
else:
|
||||
_ENDIAN = '>'
|
||||
|
@ -223,8 +210,7 @@ def _conv_type_shape(im):
|
|||
return shape+(extra,), typ
|
||||
|
||||
|
||||
MODES = _MODEINFO.keys()
|
||||
MODES.sort()
|
||||
MODES = sorted(_MODEINFO.keys())
|
||||
|
||||
# raw modes that may be memory mapped. NOTE: if you change this, you
|
||||
# may have to modify the stride calculation in map.c too!
|
||||
|
@ -293,23 +279,23 @@ def preinit():
|
|||
return
|
||||
|
||||
try:
|
||||
import BmpImagePlugin
|
||||
from . import BmpImagePlugin
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import GifImagePlugin
|
||||
from . import GifImagePlugin
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import JpegImagePlugin
|
||||
from . import JpegImagePlugin
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import PpmImagePlugin
|
||||
from . import PpmImagePlugin
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import PngImagePlugin
|
||||
from . import PngImagePlugin
|
||||
except ImportError:
|
||||
pass
|
||||
# try:
|
||||
|
@ -342,7 +328,7 @@ def init():
|
|||
# only check directories (including current, if present in the path)
|
||||
for directory in filter(isDirectory, directories):
|
||||
fullpath = os.path.abspath(directory)
|
||||
if visited.has_key(fullpath):
|
||||
if fullpath in visited:
|
||||
continue
|
||||
for file in os.listdir(directory):
|
||||
if file[-14:] == "ImagePlugin.py":
|
||||
|
@ -355,8 +341,8 @@ def init():
|
|||
del sys.path[0]
|
||||
except ImportError:
|
||||
if DEBUG:
|
||||
print "Image: failed to import",
|
||||
print f, ":", sys.exc_value
|
||||
print("Image: failed to import", end=' ')
|
||||
print(f, ":", sys.exc_info()[1])
|
||||
visited[fullpath] = None
|
||||
|
||||
if OPEN or SAVE:
|
||||
|
@ -364,21 +350,21 @@ def init():
|
|||
return 1
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Codec factories (used by tostring/fromstring and ImageFile.load)
|
||||
# Codec factories (used by tobytes/frombytes and ImageFile.load)
|
||||
|
||||
def _getdecoder(mode, decoder_name, args, extra=()):
|
||||
|
||||
# tweak arguments
|
||||
if args is None:
|
||||
args = ()
|
||||
elif not isTupleType(args):
|
||||
elif not isinstance(args, tuple):
|
||||
args = (args,)
|
||||
|
||||
try:
|
||||
# get decoder
|
||||
decoder = getattr(core, decoder_name + "_decoder")
|
||||
# print decoder, (mode,) + args + extra
|
||||
return apply(decoder, (mode,) + args + extra)
|
||||
# print(decoder, mode, args + extra)
|
||||
return decoder(mode, *args + extra)
|
||||
except AttributeError:
|
||||
raise IOError("decoder %s not available" % decoder_name)
|
||||
|
||||
|
@ -387,14 +373,14 @@ def _getencoder(mode, encoder_name, args, extra=()):
|
|||
# tweak arguments
|
||||
if args is None:
|
||||
args = ()
|
||||
elif not isTupleType(args):
|
||||
elif not isinstance(args, tuple):
|
||||
args = (args,)
|
||||
|
||||
try:
|
||||
# get encoder
|
||||
encoder = getattr(core, encoder_name + "_encoder")
|
||||
# print encoder, (mode,) + args + extra
|
||||
return apply(encoder, (mode,) + args + extra)
|
||||
# print(encoder, mode, args + extra)
|
||||
return encoder(mode, *args + extra)
|
||||
except AttributeError:
|
||||
raise IOError("encoder %s not available" % encoder_name)
|
||||
|
||||
|
@ -402,26 +388,31 @@ def _getencoder(mode, encoder_name, args, extra=()):
|
|||
# --------------------------------------------------------------------
|
||||
# Simple expression analyzer
|
||||
|
||||
def coerce_e(value):
|
||||
return value if isinstance(value, _E) else _E(value)
|
||||
|
||||
class _E:
|
||||
def __init__(self, data): self.data = data
|
||||
def __coerce__(self, other): return self, _E(other)
|
||||
def __add__(self, other): return _E((self.data, "__add__", other.data))
|
||||
def __mul__(self, other): return _E((self.data, "__mul__", other.data))
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
def __add__(self, other):
|
||||
return _E((self.data, "__add__", coerce_e(other).data))
|
||||
def __mul__(self, other):
|
||||
return _E((self.data, "__mul__", coerce_e(other).data))
|
||||
|
||||
def _getscaleoffset(expr):
|
||||
stub = ["stub"]
|
||||
data = expr(_E(stub)).data
|
||||
try:
|
||||
(a, b, c) = data # simplified syntax
|
||||
if (a is stub and b == "__mul__" and isNumberType(c)):
|
||||
if (a is stub and b == "__mul__" and isinstance(c, numbers.Number)):
|
||||
return c, 0.0
|
||||
if (a is stub and b == "__add__" and isNumberType(c)):
|
||||
if (a is stub and b == "__add__" and isinstance(c, numbers.Number)):
|
||||
return 1.0, c
|
||||
except TypeError: pass
|
||||
try:
|
||||
((a, b, c), d, e) = data # full syntax
|
||||
if (a is stub and b == "__mul__" and isNumberType(c) and
|
||||
d == "__add__" and isNumberType(e)):
|
||||
if (a is stub and b == "__mul__" and isinstance(c, numbers.Number) and
|
||||
d == "__add__" and isinstance(e, numbers.Number)):
|
||||
return c, e
|
||||
except TypeError: pass
|
||||
raise ValueError("illegal expression")
|
||||
|
@ -437,7 +428,7 @@ def _getscaleoffset(expr):
|
|||
#
|
||||
# @see #open
|
||||
# @see #new
|
||||
# @see #fromstring
|
||||
# @see #frombytes
|
||||
|
||||
class Image:
|
||||
|
||||
|
@ -462,6 +453,7 @@ class Image:
|
|||
new.size = im.size
|
||||
new.palette = self.palette
|
||||
if im.mode == "P":
|
||||
from . import ImagePalette
|
||||
new.palette = ImagePalette.ImagePalette()
|
||||
try:
|
||||
new.info = self.info.copy()
|
||||
|
@ -505,7 +497,7 @@ class Image:
|
|||
shape, typestr = _conv_type_shape(self)
|
||||
new['shape'] = shape
|
||||
new['typestr'] = typestr
|
||||
new['data'] = self.tostring()
|
||||
new['data'] = self.tobytes()
|
||||
return new
|
||||
raise AttributeError(name)
|
||||
|
||||
|
@ -515,13 +507,13 @@ class Image:
|
|||
# @param encoder_name What encoder to use. The default is to
|
||||
# use the standard "raw" encoder.
|
||||
# @param *args Extra arguments to the encoder.
|
||||
# @return An 8-bit string.
|
||||
# @return A bytes object.
|
||||
|
||||
def tostring(self, encoder_name="raw", *args):
|
||||
"Return image as a binary string"
|
||||
def tobytes(self, encoder_name="raw", *args):
|
||||
"Return image as a bytes object"
|
||||
|
||||
# may pass tuple instead of argument list
|
||||
if len(args) == 1 and isTupleType(args[0]):
|
||||
if len(args) == 1 and isinstance(args[0], tuple):
|
||||
args = args[0]
|
||||
|
||||
if encoder_name == "raw" and args == ():
|
||||
|
@ -536,15 +528,21 @@ class Image:
|
|||
bufsize = max(65536, self.size[0] * 4) # see RawEncode.c
|
||||
|
||||
data = []
|
||||
while 1:
|
||||
while True:
|
||||
l, s, d = e.encode(bufsize)
|
||||
data.append(d)
|
||||
if s:
|
||||
break
|
||||
if s < 0:
|
||||
raise RuntimeError("encoder error %d in tostring" % s)
|
||||
raise RuntimeError("encoder error %d in tobytes" % s)
|
||||
|
||||
return string.join(data, "")
|
||||
return b"".join(data)
|
||||
|
||||
if bytes is str:
|
||||
# Declare tostring as alias to tobytes
|
||||
def tostring(self, *args, **kw):
|
||||
warnings.warn('tostring() is deprecated. Please call tobytes() instead.', DeprecationWarning)
|
||||
return self.tobytes(*args, **kw)
|
||||
|
||||
##
|
||||
# Returns the image converted to an X11 bitmap. This method
|
||||
|
@ -560,23 +558,23 @@ class Image:
|
|||
self.load()
|
||||
if self.mode != "1":
|
||||
raise ValueError("not a bitmap")
|
||||
data = self.tostring("xbm")
|
||||
return string.join(["#define %s_width %d\n" % (name, self.size[0]),
|
||||
"#define %s_height %d\n"% (name, self.size[1]),
|
||||
"static char %s_bits[] = {\n" % name, data, "};"], "")
|
||||
data = self.tobytes("xbm")
|
||||
return b"".join([("#define %s_width %d\n" % (name, self.size[0])).encode('ascii'),
|
||||
("#define %s_height %d\n"% (name, self.size[1])).encode('ascii'),
|
||||
("static char %s_bits[] = {\n" % name).encode('ascii'), data, b"};"])
|
||||
|
||||
##
|
||||
# Loads this image with pixel data from a string.
|
||||
# Loads this image with pixel data from a bytes object.
|
||||
# <p>
|
||||
# This method is similar to the {@link #fromstring} function, but
|
||||
# This method is similar to the {@link #frombytes} function, but
|
||||
# loads data into this image instead of creating a new image
|
||||
# object.
|
||||
|
||||
def fromstring(self, data, decoder_name="raw", *args):
|
||||
"Load data to image from binary string"
|
||||
def frombytes(self, data, decoder_name="raw", *args):
|
||||
"Load data to image from a bytes object"
|
||||
|
||||
# may pass tuple instead of argument list
|
||||
if len(args) == 1 and isTupleType(args[0]):
|
||||
if len(args) == 1 and isinstance(args[0], tuple):
|
||||
args = args[0]
|
||||
|
||||
# default format
|
||||
|
@ -593,6 +591,12 @@ class Image:
|
|||
if s[1] != 0:
|
||||
raise ValueError("cannot decode image data")
|
||||
|
||||
if bytes is str:
|
||||
# Declare fromstring as alias to frombytes
|
||||
def fromstring(self, *args, **kw):
|
||||
warnings.warn('fromstring() is deprecated. Please call frombytes() instead.', DeprecationWarning)
|
||||
return self.frombytes(*args, **kw)
|
||||
|
||||
##
|
||||
# Allocates storage for the image and loads the pixel data. In
|
||||
# normal cases, you don't need to call this method, since the
|
||||
|
@ -605,11 +609,11 @@ class Image:
|
|||
"Explicitly load pixel data."
|
||||
if self.im and self.palette and self.palette.dirty:
|
||||
# realize palette
|
||||
apply(self.im.putpalette, self.palette.getdata())
|
||||
self.im.putpalette(*self.palette.getdata())
|
||||
self.palette.dirty = 0
|
||||
self.palette.mode = "RGB"
|
||||
self.palette.rawmode = None
|
||||
if self.info.has_key("transparency"):
|
||||
if "transparency" in self.info:
|
||||
self.im.putpalettealpha(self.info["transparency"], 0)
|
||||
self.palette.mode = "RGBA"
|
||||
if self.im:
|
||||
|
@ -802,7 +806,7 @@ class Image:
|
|||
|
||||
self.load()
|
||||
|
||||
if callable(filter):
|
||||
if isinstance(filter, collections.Callable):
|
||||
filter = filter()
|
||||
if not hasattr(filter, "filter"):
|
||||
raise TypeError("filter argument should be ImageFilter.Filter instance or class")
|
||||
|
@ -907,12 +911,12 @@ class Image:
|
|||
return self.im.getextrema()
|
||||
|
||||
##
|
||||
# Returns a PyCObject that points to the internal image memory.
|
||||
# Returns a capsule that points to the internal image memory.
|
||||
#
|
||||
# @return A PyCObject object.
|
||||
# @return A capsule object.
|
||||
|
||||
def getim(self):
|
||||
"Get PyCObject pointer to internal image memory"
|
||||
"Get capsule pointer to internal image memory"
|
||||
|
||||
self.load()
|
||||
return self.im.ptr
|
||||
|
@ -929,7 +933,10 @@ class Image:
|
|||
|
||||
self.load()
|
||||
try:
|
||||
return map(ord, self.im.getpalette())
|
||||
if bytes is str:
|
||||
return [i8(c) for c in self.im.getpalette()]
|
||||
else:
|
||||
return list(self.im.getpalette())
|
||||
except ValueError:
|
||||
return None # no palette
|
||||
|
||||
|
@ -958,7 +965,7 @@ class Image:
|
|||
|
||||
self.load()
|
||||
x, y = self.im.getprojection()
|
||||
return map(ord, x), map(ord, y)
|
||||
return [i8(c) for c in x], [i8(c) for c in y]
|
||||
|
||||
##
|
||||
# Returns a histogram for the image. The histogram is returned as
|
||||
|
@ -1012,7 +1019,7 @@ class Image:
|
|||
"'offset' is deprecated; use 'ImageChops.offset' instead",
|
||||
DeprecationWarning, stacklevel=2
|
||||
)
|
||||
import ImageChops
|
||||
from . import ImageChops
|
||||
return ImageChops.offset(self, xoffset, yoffset)
|
||||
|
||||
##
|
||||
|
@ -1079,7 +1086,7 @@ class Image:
|
|||
box = box + (box[0]+size[0], box[1]+size[1])
|
||||
|
||||
if isStringType(im):
|
||||
import ImageColor
|
||||
from . import ImageColor
|
||||
im = ImageColor.getcolor(im, self.mode)
|
||||
|
||||
elif isImageType(im):
|
||||
|
@ -1121,14 +1128,14 @@ class Image:
|
|||
if isinstance(lut, ImagePointHandler):
|
||||
return lut.point(self)
|
||||
|
||||
if not isSequenceType(lut):
|
||||
if not isinstance(lut, collections.Sequence):
|
||||
# if it isn't a list, it should be a function
|
||||
if self.mode in ("I", "I;16", "F"):
|
||||
# check if the function can be used with point_transform
|
||||
scale, offset = _getscaleoffset(lut)
|
||||
return self._new(self.im.point_transform(scale, offset))
|
||||
# for other modes, convert the function to a table
|
||||
lut = map(lut, range(256)) * self.im.bands
|
||||
lut = [lut(i) for i in range(256)] * self.im.bands
|
||||
|
||||
if self.mode == "F":
|
||||
# FIXME: _imaging returns a confusing error message for this case
|
||||
|
@ -1225,6 +1232,7 @@ class Image:
|
|||
|
||||
def putpalette(self, data, rawmode="RGB"):
|
||||
"Put palette data into an image."
|
||||
from . import ImagePalette
|
||||
|
||||
if self.mode not in ("L", "P"):
|
||||
raise ValueError("illegal image mode")
|
||||
|
@ -1232,8 +1240,11 @@ class Image:
|
|||
if isinstance(data, ImagePalette.ImagePalette):
|
||||
palette = ImagePalette.raw(data.rawmode, data.palette)
|
||||
else:
|
||||
if not isStringType(data):
|
||||
data = string.join(map(chr, data), "")
|
||||
if not isinstance(data, bytes):
|
||||
if bytes is str:
|
||||
data = "".join(chr(x) for x in data)
|
||||
else:
|
||||
data = bytes(data)
|
||||
palette = ImagePalette.raw(rawmode, data)
|
||||
self.mode = "P"
|
||||
self.palette = palette
|
||||
|
@ -1330,7 +1341,8 @@ class Image:
|
|||
math.cos(angle), math.sin(angle), 0.0,
|
||||
-math.sin(angle), math.cos(angle), 0.0
|
||||
]
|
||||
def transform(x, y, (a, b, c, d, e, f)=matrix):
|
||||
def transform(x, y, matrix=matrix):
|
||||
(a, b, c, d, e, f) = matrix
|
||||
return a*x + b*y + c, d*x + e*y + f
|
||||
|
||||
# calculate output size
|
||||
|
@ -1408,7 +1420,7 @@ class Image:
|
|||
|
||||
preinit()
|
||||
|
||||
ext = string.lower(os.path.splitext(filename)[1])
|
||||
ext = os.path.splitext(filename)[1].lower()
|
||||
|
||||
if not format:
|
||||
try:
|
||||
|
@ -1421,14 +1433,13 @@ class Image:
|
|||
raise KeyError(ext) # unknown extension
|
||||
|
||||
try:
|
||||
save_handler = SAVE[string.upper(format)]
|
||||
save_handler = SAVE[format.upper()]
|
||||
except KeyError:
|
||||
init()
|
||||
save_handler = SAVE[string.upper(format)] # unknown format
|
||||
save_handler = SAVE[format.upper()] # unknown format
|
||||
|
||||
if isStringType(fp):
|
||||
import __builtin__
|
||||
fp = __builtin__.open(fp, "wb")
|
||||
fp = builtins.open(fp, "wb")
|
||||
close = 1
|
||||
else:
|
||||
close = 0
|
||||
|
@ -1755,13 +1766,13 @@ def new(mode, size, color=0):
|
|||
if isStringType(color):
|
||||
# css3-style specifier
|
||||
|
||||
import ImageColor
|
||||
from . import ImageColor
|
||||
color = ImageColor.getcolor(color, mode)
|
||||
|
||||
return Image()._new(core.fill(mode, size, color))
|
||||
|
||||
##
|
||||
# Creates an image memory from pixel data in a string.
|
||||
# Creates a copy of an image memory from pixel data in a buffer.
|
||||
# <p>
|
||||
# In its simplest form, this function takes three arguments
|
||||
# (mode, size, and unpacked pixel data).
|
||||
|
@ -1772,34 +1783,40 @@ def new(mode, size, color=0):
|
|||
# <p>
|
||||
# Note that this function decodes pixel data only, not entire images.
|
||||
# If you have an entire image in a string, wrap it in a
|
||||
# <b>StringIO</b> object, and use {@link #open} to load it.
|
||||
# <b>BytesIO</b> object, and use {@link #open} to load it.
|
||||
#
|
||||
# @param mode The image mode.
|
||||
# @param size The image size.
|
||||
# @param data An 8-bit string containing raw data for the given mode.
|
||||
# @param data A byte buffer containing raw data for the given mode.
|
||||
# @param decoder_name What decoder to use.
|
||||
# @param *args Additional parameters for the given decoder.
|
||||
# @return An Image object.
|
||||
|
||||
def fromstring(mode, size, data, decoder_name="raw", *args):
|
||||
"Load image from string"
|
||||
def frombytes(mode, size, data, decoder_name="raw", *args):
|
||||
"Load image from byte buffer"
|
||||
|
||||
# may pass tuple instead of argument list
|
||||
if len(args) == 1 and isTupleType(args[0]):
|
||||
if len(args) == 1 and isinstance(args[0], tuple):
|
||||
args = args[0]
|
||||
|
||||
if decoder_name == "raw" and args == ():
|
||||
args = mode
|
||||
|
||||
im = new(mode, size)
|
||||
im.fromstring(data, decoder_name, args)
|
||||
im.frombytes(data, decoder_name, args)
|
||||
return im
|
||||
|
||||
if bytes is str:
|
||||
# Declare fromstring as an alias for frombytes
|
||||
def fromstring(*args, **kw):
|
||||
warnings.warn('fromstring() is deprecated. Please call frombytes() instead.', DeprecationWarning)
|
||||
return frombytes(*args, **kw)
|
||||
|
||||
##
|
||||
# (New in 1.1.4) Creates an image memory from pixel data in a string
|
||||
# or byte buffer.
|
||||
# (New in 1.1.4) Creates an image memory referencing pixel data in a
|
||||
# byte buffer.
|
||||
# <p>
|
||||
# This function is similar to {@link #fromstring}, but uses data in
|
||||
# This function is similar to {@link #frombytes}, but uses data in
|
||||
# the byte buffer, where possible. This means that changes to the
|
||||
# original buffer object are reflected in this image). Not all modes
|
||||
# can share memory; supported modes include "L", "RGBX", "RGBA", and
|
||||
|
@ -1807,7 +1824,7 @@ def fromstring(mode, size, data, decoder_name="raw", *args):
|
|||
# <p>
|
||||
# Note that this function decodes pixel data only, not entire images.
|
||||
# If you have an entire image file in a string, wrap it in a
|
||||
# <b>StringIO</b> object, and use {@link #open} to load it.
|
||||
# <b>BytesIO</b> object, and use {@link #open} to load it.
|
||||
# <p>
|
||||
# In the current version, the default parameters used for the "raw"
|
||||
# decoder differs from that used for {@link fromstring}. This is a
|
||||
|
@ -1818,7 +1835,7 @@ def fromstring(mode, size, data, decoder_name="raw", *args):
|
|||
#
|
||||
# @param mode The image mode.
|
||||
# @param size The image size.
|
||||
# @param data An 8-bit string or other buffer object containing raw
|
||||
# @param data A bytes or other buffer object containing raw
|
||||
# data for the given mode.
|
||||
# @param decoder_name What decoder to use.
|
||||
# @param *args Additional parameters for the given decoder. For the
|
||||
|
@ -1829,10 +1846,10 @@ def fromstring(mode, size, data, decoder_name="raw", *args):
|
|||
# @since 1.1.4
|
||||
|
||||
def frombuffer(mode, size, data, decoder_name="raw", *args):
|
||||
"Load image from string or buffer"
|
||||
"Load image from bytes or buffer"
|
||||
|
||||
# may pass tuple instead of argument list
|
||||
if len(args) == 1 and isTupleType(args[0]):
|
||||
if len(args) == 1 and isinstance(args[0], tuple):
|
||||
args = args[0]
|
||||
|
||||
if decoder_name == "raw":
|
||||
|
@ -1853,14 +1870,14 @@ def frombuffer(mode, size, data, decoder_name="raw", *args):
|
|||
im.readonly = 1
|
||||
return im
|
||||
|
||||
return fromstring(mode, size, data, decoder_name, args)
|
||||
return frombytes(mode, size, data, decoder_name, args)
|
||||
|
||||
|
||||
##
|
||||
# (New in 1.1.6) Creates an image memory from an object exporting
|
||||
# the array interface (using the buffer protocol).
|
||||
#
|
||||
# If obj is not contiguous, then the tostring method is called
|
||||
# If obj is not contiguous, then the tobytes method is called
|
||||
# and {@link frombuffer} is used.
|
||||
#
|
||||
# @param obj Object with array interface
|
||||
|
@ -1895,7 +1912,7 @@ def fromarray(obj, mode=None):
|
|||
|
||||
size = shape[1], shape[0]
|
||||
if strides is not None:
|
||||
obj = obj.tostring()
|
||||
obj = obj.tobytes()
|
||||
|
||||
return frombuffer(mode, size, obj, "raw", rawmode, 0, 1)
|
||||
|
||||
|
@ -1945,9 +1962,8 @@ def open(fp, mode="r"):
|
|||
raise ValueError("bad mode")
|
||||
|
||||
if isStringType(fp):
|
||||
import __builtin__
|
||||
filename = fp
|
||||
fp = __builtin__.open(fp, "rb")
|
||||
fp = builtins.open(fp, "rb")
|
||||
else:
|
||||
filename = ""
|
||||
|
||||
|
@ -1962,6 +1978,8 @@ def open(fp, mode="r"):
|
|||
fp.seek(0)
|
||||
return factory(fp, filename)
|
||||
except (SyntaxError, IndexError, TypeError):
|
||||
#import traceback
|
||||
#traceback.print_exc()
|
||||
pass
|
||||
|
||||
if init():
|
||||
|
@ -1973,6 +1991,8 @@ def open(fp, mode="r"):
|
|||
fp.seek(0)
|
||||
return factory(fp, filename)
|
||||
except (SyntaxError, IndexError, TypeError):
|
||||
#import traceback
|
||||
#traceback.print_exc()
|
||||
pass
|
||||
|
||||
raise IOError("cannot identify image file")
|
||||
|
@ -2093,7 +2113,7 @@ def merge(mode, bands):
|
|||
# reject images having another format.
|
||||
|
||||
def register_open(id, factory, accept=None):
|
||||
id = string.upper(id)
|
||||
id = id.upper()
|
||||
ID.append(id)
|
||||
OPEN[id] = factory, accept
|
||||
|
||||
|
@ -2105,7 +2125,7 @@ def register_open(id, factory, accept=None):
|
|||
# @param mimetype The image MIME type for this format.
|
||||
|
||||
def register_mime(id, mimetype):
|
||||
MIME[string.upper(id)] = mimetype
|
||||
MIME[id.upper()] = mimetype
|
||||
|
||||
##
|
||||
# Registers an image save function. This function should not be
|
||||
|
@ -2115,7 +2135,7 @@ def register_mime(id, mimetype):
|
|||
# @param driver A function to save images in this format.
|
||||
|
||||
def register_save(id, driver):
|
||||
SAVE[string.upper(id)] = driver
|
||||
SAVE[id.upper()] = driver
|
||||
|
||||
##
|
||||
# Registers an image extension. This function should not be
|
||||
|
@ -2125,7 +2145,7 @@ def register_save(id, driver):
|
|||
# @param extension An extension used for this format.
|
||||
|
||||
def register_extension(id, extension):
|
||||
EXTENSION[string.lower(extension)] = string.upper(id)
|
||||
EXTENSION[extension.lower()] = id.upper()
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -2133,8 +2153,8 @@ def register_extension(id, extension):
|
|||
|
||||
def _show(image, **options):
|
||||
# override me, as necessary
|
||||
apply(_showxv, (image,), options)
|
||||
_showxv(image, **options)
|
||||
|
||||
def _showxv(image, title=None, **options):
|
||||
import ImageShow
|
||||
apply(ImageShow.show, (image, title), options)
|
||||
from . import ImageShow
|
||||
ImageShow.show(image, title, **options)
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
from . import Image
|
||||
|
||||
##
|
||||
# The <b>ImageChops</b> module contains a number of arithmetical image
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
# below for the original description.
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
DESCRIPTION = """
|
||||
pyCMS
|
||||
|
||||
|
@ -79,7 +81,7 @@ VERSION = "0.1.0 pil"
|
|||
|
||||
# --------------------------------------------------------------------.
|
||||
|
||||
import Image
|
||||
from . import Image
|
||||
import _imagingcms
|
||||
|
||||
core = _imagingcms
|
||||
|
@ -122,7 +124,7 @@ FLAGS = {
|
|||
|
||||
_MAX_FLAG = 0
|
||||
for flag in FLAGS.values():
|
||||
if isinstance(flag, type(0)):
|
||||
if isinstance(flag, int):
|
||||
_MAX_FLAG = _MAX_FLAG | flag
|
||||
|
||||
# --------------------------------------------------------------------.
|
||||
|
@ -140,7 +142,7 @@ class ImageCmsProfile:
|
|||
if Image.isStringType(profile):
|
||||
self._set(core.profile_open(profile), profile)
|
||||
elif hasattr(profile, "read"):
|
||||
self._set(core.profile_fromstring(profile.read()))
|
||||
self._set(core.profile_frombytes(profile.read()))
|
||||
else:
|
||||
self._set(profile) # assume it's already a profile
|
||||
|
||||
|
@ -205,7 +207,7 @@ class ImageCmsTransform(Image.ImagePointHandler):
|
|||
def get_display_profile(handle=None):
|
||||
import sys
|
||||
if sys.platform == "win32":
|
||||
import ImageWin
|
||||
from . import ImageWin
|
||||
if isinstance(handle, ImageWin.HDC):
|
||||
profile = core.get_display_profile_win32(handle, 1)
|
||||
else:
|
||||
|
@ -288,10 +290,10 @@ def profileToProfile(im, inputProfile, outputProfile, renderingIntent=INTENT_PER
|
|||
if outputMode is None:
|
||||
outputMode = im.mode
|
||||
|
||||
if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3):
|
||||
if not isinstance(renderingIntent, int) or not (0 <= renderingIntent <=3):
|
||||
raise PyCMSError("renderingIntent must be an integer between 0 and 3")
|
||||
|
||||
if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG):
|
||||
if not isinstance(flags, int) or not (0 <= flags <= _MAX_FLAG):
|
||||
raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG)
|
||||
|
||||
try:
|
||||
|
@ -307,7 +309,7 @@ def profileToProfile(im, inputProfile, outputProfile, renderingIntent=INTENT_PER
|
|||
imOut = None
|
||||
else:
|
||||
imOut = transform.apply(im)
|
||||
except (IOError, TypeError, ValueError), v:
|
||||
except (IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
return imOut
|
||||
|
@ -334,7 +336,7 @@ def getOpenProfile(profileFilename):
|
|||
|
||||
try:
|
||||
return ImageCmsProfile(profileFilename)
|
||||
except (IOError, TypeError, ValueError), v:
|
||||
except (IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
##
|
||||
|
@ -396,10 +398,10 @@ def buildTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent
|
|||
|
||||
"""
|
||||
|
||||
if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3):
|
||||
if not isinstance(renderingIntent, int) or not (0 <= renderingIntent <=3):
|
||||
raise PyCMSError("renderingIntent must be an integer between 0 and 3")
|
||||
|
||||
if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG):
|
||||
if not isinstance(flags, int) or not (0 <= flags <= _MAX_FLAG):
|
||||
raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG)
|
||||
|
||||
try:
|
||||
|
@ -408,7 +410,7 @@ def buildTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent
|
|||
if not isinstance(outputProfile, ImageCmsProfile):
|
||||
outputProfile = ImageCmsProfile(outputProfile)
|
||||
return ImageCmsTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent, flags=flags)
|
||||
except (IOError, TypeError, ValueError), v:
|
||||
except (IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
##
|
||||
|
@ -487,10 +489,10 @@ def buildProofTransform(inputProfile, outputProfile, proofProfile, inMode, outMo
|
|||
|
||||
"""
|
||||
|
||||
if type(renderingIntent) != type(1) or not (0 <= renderingIntent <=3):
|
||||
if not isinstance(renderingIntent, int) or not (0 <= renderingIntent <=3):
|
||||
raise PyCMSError("renderingIntent must be an integer between 0 and 3")
|
||||
|
||||
if type(flags) != type(1) or not (0 <= flags <= _MAX_FLAG):
|
||||
if not isinstance(flags, int) or not (0 <= flags <= _MAX_FLAG):
|
||||
raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG)
|
||||
|
||||
try:
|
||||
|
@ -501,7 +503,7 @@ def buildProofTransform(inputProfile, outputProfile, proofProfile, inMode, outMo
|
|||
if not isinstance(proofProfile, ImageCmsProfile):
|
||||
proofProfile = ImageCmsProfile(proofProfile)
|
||||
return ImageCmsTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent, proofProfile, proofRenderingIntent, flags)
|
||||
except (IOError, TypeError, ValueError), v:
|
||||
except (IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
buildTransformFromOpenProfiles = buildTransform
|
||||
|
@ -557,7 +559,7 @@ def applyTransform(im, transform, inPlace=0):
|
|||
imOut = None
|
||||
else:
|
||||
imOut = transform.apply(im)
|
||||
except (TypeError, ValueError), v:
|
||||
except (TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
return imOut
|
||||
|
@ -595,14 +597,14 @@ def createProfile(colorSpace, colorTemp=-1):
|
|||
raise PyCMSError("Color space not supported for on-the-fly profile creation (%s)" % colorSpace)
|
||||
|
||||
if colorSpace == "LAB":
|
||||
if type(colorTemp) == type(5000.0):
|
||||
if isinstance(colorTemp, float):
|
||||
colorTemp = int(colorTemp + 0.5)
|
||||
if type (colorTemp) != type (5000):
|
||||
if not isinstance(colorTemp, int):
|
||||
raise PyCMSError("Color temperature must be a positive integer, \"%s\" not valid" % colorTemp)
|
||||
|
||||
try:
|
||||
return core.createProfile(colorSpace, colorTemp)
|
||||
except (TypeError, ValueError), v:
|
||||
except (TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
##
|
||||
|
@ -633,7 +635,7 @@ def getProfileName(profile):
|
|||
if not isinstance(profile, ImageCmsProfile):
|
||||
profile = ImageCmsProfile(profile)
|
||||
return profile.profile.product_name + "\n"
|
||||
except (AttributeError, IOError, TypeError, ValueError), v:
|
||||
except (AttributeError, IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
##
|
||||
|
@ -665,7 +667,7 @@ def getProfileInfo(profile):
|
|||
profile = ImageCmsProfile(profile)
|
||||
# add an extra newline to preserve pyCMS compatibility
|
||||
return profile.product_info + "\n"
|
||||
except (AttributeError, IOError, TypeError, ValueError), v:
|
||||
except (AttributeError, IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
##
|
||||
|
@ -703,7 +705,7 @@ def getDefaultIntent(profile):
|
|||
if not isinstance(profile, ImageCmsProfile):
|
||||
profile = ImageCmsProfile(profile)
|
||||
return profile.profile.rendering_intent
|
||||
except (AttributeError, IOError, TypeError, ValueError), v:
|
||||
except (AttributeError, IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
##
|
||||
|
@ -752,7 +754,7 @@ def isIntentSupported(profile, intent, direction):
|
|||
return 1
|
||||
else:
|
||||
return -1
|
||||
except (AttributeError, IOError, TypeError, ValueError), v:
|
||||
except (AttributeError, IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
##
|
||||
|
@ -769,18 +771,17 @@ def versions():
|
|||
if __name__ == "__main__":
|
||||
# create a cheap manual from the __doc__ strings for the functions above
|
||||
|
||||
import ImageCms
|
||||
import string
|
||||
print __doc__
|
||||
from . import ImageCms
|
||||
print(__doc__)
|
||||
|
||||
for f in dir(pyCMS):
|
||||
print "="*80
|
||||
print "%s" %f
|
||||
print("="*80)
|
||||
print("%s" %f)
|
||||
|
||||
try:
|
||||
exec ("doc = ImageCms.%s.__doc__" %(f))
|
||||
if string.find(doc, "pyCMS") >= 0:
|
||||
if "pyCMS" in doc:
|
||||
# so we don't get the __doc__ string for imported modules
|
||||
print doc
|
||||
print(doc)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
|
|
@ -17,16 +17,9 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
import re, string
|
||||
from . import Image
|
||||
import re
|
||||
|
||||
try:
|
||||
x = int("a", 16)
|
||||
except TypeError:
|
||||
# python 1.5.2 doesn't support int(x,b)
|
||||
str2int = string.atoi
|
||||
else:
|
||||
str2int = int
|
||||
|
||||
##
|
||||
# Convert color string to RGB tuple.
|
||||
|
@ -43,12 +36,12 @@ def getrgb(color):
|
|||
except KeyError:
|
||||
try:
|
||||
# fall back on case-insensitive lookup
|
||||
rgb = colormap[string.lower(color)]
|
||||
rgb = colormap[color.lower()]
|
||||
except KeyError:
|
||||
rgb = None
|
||||
# found color in cache
|
||||
if rgb:
|
||||
if isinstance(rgb, type(())):
|
||||
if isinstance(rgb, tuple):
|
||||
return rgb
|
||||
colormap[color] = rgb = getrgb(rgb)
|
||||
return rgb
|
||||
|
@ -56,30 +49,30 @@ def getrgb(color):
|
|||
m = re.match("#\w\w\w$", color)
|
||||
if m:
|
||||
return (
|
||||
str2int(color[1]*2, 16),
|
||||
str2int(color[2]*2, 16),
|
||||
str2int(color[3]*2, 16)
|
||||
int(color[1]*2, 16),
|
||||
int(color[2]*2, 16),
|
||||
int(color[3]*2, 16)
|
||||
)
|
||||
m = re.match("#\w\w\w\w\w\w$", color)
|
||||
if m:
|
||||
return (
|
||||
str2int(color[1:3], 16),
|
||||
str2int(color[3:5], 16),
|
||||
str2int(color[5:7], 16)
|
||||
int(color[1:3], 16),
|
||||
int(color[3:5], 16),
|
||||
int(color[5:7], 16)
|
||||
)
|
||||
m = re.match("rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$", color)
|
||||
if m:
|
||||
return (
|
||||
str2int(m.group(1)),
|
||||
str2int(m.group(2)),
|
||||
str2int(m.group(3))
|
||||
int(m.group(1)),
|
||||
int(m.group(2)),
|
||||
int(m.group(3))
|
||||
)
|
||||
m = re.match("rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$", color)
|
||||
if m:
|
||||
return (
|
||||
int((str2int(m.group(1)) * 255) / 100.0 + 0.5),
|
||||
int((str2int(m.group(2)) * 255) / 100.0 + 0.5),
|
||||
int((str2int(m.group(3)) * 255) / 100.0 + 0.5)
|
||||
int((int(m.group(1)) * 255) / 100.0 + 0.5),
|
||||
int((int(m.group(2)) * 255) / 100.0 + 0.5),
|
||||
int((int(m.group(3)) * 255) / 100.0 + 0.5)
|
||||
)
|
||||
m = re.match("hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$", color)
|
||||
if m:
|
||||
|
@ -106,7 +99,7 @@ def getcolor(color, mode):
|
|||
return r, g, b, 255
|
||||
if Image.getmodebase(mode) == "L":
|
||||
r, g, b = color
|
||||
return (r*299 + g*587 + b*114)/1000
|
||||
return (r*299 + g*587 + b*114)//1000
|
||||
return color
|
||||
|
||||
colormap = {
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageColor
|
||||
from . import Image, ImageColor
|
||||
|
||||
try:
|
||||
import warnings
|
||||
|
@ -127,7 +127,7 @@ class ImageDraw:
|
|||
def getfont(self):
|
||||
if not self.font:
|
||||
# FIXME: should add a font repository
|
||||
import ImageFont
|
||||
from . import ImageFont
|
||||
self.font = ImageFont.load_default()
|
||||
return self.font
|
||||
|
||||
|
@ -318,7 +318,7 @@ def getdraw(im=None, hints=None):
|
|||
except ImportError:
|
||||
pass
|
||||
if handler is None:
|
||||
import ImageDraw2
|
||||
from . import ImageDraw2
|
||||
handler = ImageDraw2
|
||||
if im:
|
||||
im = handler.Draw(im)
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageColor, ImageDraw, ImageFont, ImagePath
|
||||
from . import Image, ImageColor, ImageDraw, ImageFont, ImagePath
|
||||
|
||||
class Pen:
|
||||
def __init__(self, color, width=1, opacity=255):
|
||||
|
@ -68,7 +68,8 @@ class Draw:
|
|||
else:
|
||||
getattr(self.draw, op)(xy, fill=fill, outline=outline)
|
||||
|
||||
def settransform(self, (xoffset, yoffset)):
|
||||
def settransform(self, offset):
|
||||
(xoffset, yoffset) = offset
|
||||
self.transform = (1, 0, xoffset, 0, 1, yoffset)
|
||||
|
||||
def arc(self, xy, start, end, *options):
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image, ImageFilter, ImageStat
|
||||
from . import Image, ImageFilter, ImageStat
|
||||
|
||||
class _Enhance:
|
||||
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
import traceback, string, os
|
||||
from . import Image
|
||||
import traceback, os
|
||||
import io
|
||||
|
||||
MAXBLOCK = 65536
|
||||
|
||||
|
@ -55,9 +56,9 @@ def raise_ioerror(error):
|
|||
# --------------------------------------------------------------------
|
||||
# Helpers
|
||||
|
||||
def _tilesort(t1, t2):
|
||||
def _tilesort(t):
|
||||
# sort on offset
|
||||
return cmp(t1[2], t2[2])
|
||||
return t[2]
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -89,25 +90,25 @@ class ImageFile(Image.Image):
|
|||
|
||||
try:
|
||||
self._open()
|
||||
except IndexError, v: # end of data
|
||||
except IndexError as v: # end of data
|
||||
if Image.DEBUG > 1:
|
||||
traceback.print_exc()
|
||||
raise SyntaxError, v
|
||||
except TypeError, v: # end of data (ord)
|
||||
raise SyntaxError(v)
|
||||
except TypeError as v: # end of data (ord)
|
||||
if Image.DEBUG > 1:
|
||||
traceback.print_exc()
|
||||
raise SyntaxError, v
|
||||
except KeyError, v: # unsupported mode
|
||||
raise SyntaxError(v)
|
||||
except KeyError as v: # unsupported mode
|
||||
if Image.DEBUG > 1:
|
||||
traceback.print_exc()
|
||||
raise SyntaxError, v
|
||||
except EOFError, v: # got header but not the first frame
|
||||
raise SyntaxError(v)
|
||||
except EOFError as v: # got header but not the first frame
|
||||
if Image.DEBUG > 1:
|
||||
traceback.print_exc()
|
||||
raise SyntaxError, v
|
||||
raise SyntaxError(v)
|
||||
|
||||
if not self.mode or self.size[0] <= 0:
|
||||
raise SyntaxError, "not identified by this driver"
|
||||
raise SyntaxError("not identified by this driver")
|
||||
|
||||
def draft(self, mode, size):
|
||||
"Set draft mode"
|
||||
|
@ -177,13 +178,13 @@ class ImageFile(Image.Image):
|
|||
if not self.map:
|
||||
|
||||
# sort tiles in file order
|
||||
self.tile.sort(_tilesort)
|
||||
self.tile.sort(key=_tilesort)
|
||||
|
||||
try:
|
||||
# FIXME: This is a hack to handle TIFF's JpegTables tag.
|
||||
prefix = self.tile_prefix
|
||||
except AttributeError:
|
||||
prefix = ""
|
||||
prefix = b""
|
||||
|
||||
for d, e, o, a in self.tile:
|
||||
d = Image._getdecoder(self.mode, d, a, self.decoderconfig)
|
||||
|
@ -194,7 +195,7 @@ class ImageFile(Image.Image):
|
|||
continue
|
||||
b = prefix
|
||||
t = len(b)
|
||||
while 1:
|
||||
while True:
|
||||
s = read(self.decodermaxblock)
|
||||
if not s:
|
||||
self.tile = []
|
||||
|
@ -277,52 +278,6 @@ class StubImageFile(ImageFile):
|
|||
"StubImageFile subclass must implement _load"
|
||||
)
|
||||
|
||||
##
|
||||
# (Internal) Support class for the <b>Parser</b> file.
|
||||
|
||||
class _ParserFile:
|
||||
# parser support class.
|
||||
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
self.offset = 0
|
||||
|
||||
def close(self):
|
||||
self.data = self.offset = None
|
||||
|
||||
def tell(self):
|
||||
return self.offset
|
||||
|
||||
def seek(self, offset, whence=0):
|
||||
if whence == 0:
|
||||
self.offset = offset
|
||||
elif whence == 1:
|
||||
self.offset = self.offset + offset
|
||||
else:
|
||||
# force error in Image.open
|
||||
raise IOError("illegal argument to seek")
|
||||
|
||||
def read(self, bytes=0):
|
||||
pos = self.offset
|
||||
if bytes:
|
||||
data = self.data[pos:pos+bytes]
|
||||
else:
|
||||
data = self.data[pos:]
|
||||
self.offset = pos + len(data)
|
||||
return data
|
||||
|
||||
def readline(self):
|
||||
# FIXME: this is slow!
|
||||
s = ""
|
||||
while 1:
|
||||
c = self.read(1)
|
||||
if not c:
|
||||
break
|
||||
s = s + c
|
||||
if c == "\n":
|
||||
break
|
||||
return s
|
||||
|
||||
##
|
||||
# Incremental image parser. This class implements the standard
|
||||
# feed/close consumer interface.
|
||||
|
@ -398,11 +353,12 @@ class Parser:
|
|||
# attempt to open this file
|
||||
try:
|
||||
try:
|
||||
fp = _ParserFile(self.data)
|
||||
fp = io.BytesIO(self.data)
|
||||
im = Image.open(fp)
|
||||
finally:
|
||||
fp.close() # explicitly close the virtual file
|
||||
except IOError:
|
||||
# traceback.print_exc()
|
||||
pass # not enough data
|
||||
else:
|
||||
flag = hasattr(im, "load_seek") or hasattr(im, "load_read")
|
||||
|
@ -437,7 +393,7 @@ class Parser:
|
|||
# finish decoding
|
||||
if self.decoder:
|
||||
# get rid of what's left in the buffers
|
||||
self.feed("")
|
||||
self.feed(b"")
|
||||
self.data = self.decoder = None
|
||||
if not self.finished:
|
||||
raise IOError("image was incomplete")
|
||||
|
@ -447,7 +403,7 @@ class Parser:
|
|||
# incremental parsing not possible; reopen the file
|
||||
# not that we have all data
|
||||
try:
|
||||
fp = _ParserFile(self.data)
|
||||
fp = io.BytesIO(self.data)
|
||||
self.image = Image.open(fp)
|
||||
finally:
|
||||
self.image.load()
|
||||
|
@ -469,20 +425,20 @@ def _save(im, fp, tile):
|
|||
im.load()
|
||||
if not hasattr(im, "encoderconfig"):
|
||||
im.encoderconfig = ()
|
||||
tile.sort(_tilesort)
|
||||
tile.sort(key=_tilesort)
|
||||
# FIXME: make MAXBLOCK a configuration parameter
|
||||
bufsize = max(MAXBLOCK, im.size[0] * 4) # see RawEncode.c
|
||||
try:
|
||||
fh = fp.fileno()
|
||||
fp.flush()
|
||||
except AttributeError:
|
||||
except (AttributeError, io.UnsupportedOperation):
|
||||
# compress to Python file-compatible object
|
||||
for e, b, o, a in tile:
|
||||
e = Image._getencoder(im.mode, e, a, im.encoderconfig)
|
||||
if o > 0:
|
||||
fp.seek(o, 0)
|
||||
e.setimage(im.im, b)
|
||||
while 1:
|
||||
while True:
|
||||
l, s, d = e.encode(bufsize)
|
||||
fp.write(d)
|
||||
if s:
|
||||
|
@ -515,7 +471,7 @@ def _save(im, fp, tile):
|
|||
|
||||
def _safe_read(fp, size):
|
||||
if size <= 0:
|
||||
return ""
|
||||
return b""
|
||||
if size <= SAFEBLOCK:
|
||||
return fp.read(size)
|
||||
data = []
|
||||
|
@ -525,4 +481,4 @@ def _safe_read(fp, size):
|
|||
break
|
||||
data.append(block)
|
||||
size = size - len(block)
|
||||
return string.join(data, "")
|
||||
return b"".join(data)
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
from StringIO import StringIO
|
||||
from io import BytesIO
|
||||
|
||||
##
|
||||
# The <b>ImageFileIO</b> module can be used to read an image from a
|
||||
|
@ -23,7 +23,7 @@ from StringIO import StringIO
|
|||
#
|
||||
# @see ImageFile#Parser
|
||||
|
||||
class ImageFileIO(StringIO):
|
||||
class ImageFileIO(BytesIO):
|
||||
|
||||
##
|
||||
# Adds buffering to a stream file object, in order to
|
||||
|
@ -36,4 +36,4 @@ class ImageFileIO(StringIO):
|
|||
|
||||
def __init__(self, fp):
|
||||
data = fp.read()
|
||||
StringIO.__init__(self, data)
|
||||
BytesIO.__init__(self, data)
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
from functools import reduce
|
||||
|
||||
class Filter:
|
||||
pass
|
||||
|
||||
|
@ -52,7 +54,7 @@ class Kernel(Filter):
|
|||
def filter(self, image):
|
||||
if image.mode == "P":
|
||||
raise ValueError("cannot filter palette images")
|
||||
return apply(image.filter, self.filterargs)
|
||||
return image.filter(*self.filterargs)
|
||||
|
||||
class BuiltinFilter(Kernel):
|
||||
def __init__(self):
|
||||
|
@ -80,7 +82,7 @@ class RankFilter(Filter):
|
|||
def filter(self, image):
|
||||
if image.mode == "P":
|
||||
raise ValueError("cannot filter palette images")
|
||||
image = image.expand(self.size/2, self.size/2)
|
||||
image = image.expand(self.size//2, self.size//2)
|
||||
return image.rankfilter(self.size, self.rank)
|
||||
|
||||
##
|
||||
|
@ -97,7 +99,7 @@ class MedianFilter(RankFilter):
|
|||
|
||||
def __init__(self, size=3):
|
||||
self.size = size
|
||||
self.rank = size*size/2
|
||||
self.rank = size*size//2
|
||||
|
||||
##
|
||||
# Min filter. Picks the lowest pixel value in a window with the given
|
||||
|
|
|
@ -25,8 +25,10 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
import os, string, sys
|
||||
from __future__ import print_function
|
||||
|
||||
from . import Image
|
||||
import os, sys
|
||||
|
||||
class _imagingft_not_installed:
|
||||
# module placeholder
|
||||
|
@ -97,13 +99,13 @@ class ImageFont:
|
|||
def _load_pilfont_data(self, file, image):
|
||||
|
||||
# read PILfont header
|
||||
if file.readline() != "PILfont\n":
|
||||
if file.readline() != b"PILfont\n":
|
||||
raise SyntaxError("Not a PILfont file")
|
||||
d = string.split(file.readline(), ";")
|
||||
d = file.readline().split(b";")
|
||||
self.info = [] # FIXME: should be a dictionary
|
||||
while True:
|
||||
s = file.readline()
|
||||
if not s or s == "DATA\n":
|
||||
if not s or s == b"DATA\n":
|
||||
break
|
||||
self.info.append(s)
|
||||
|
||||
|
@ -253,12 +255,12 @@ def load_path(filename):
|
|||
|
||||
def load_default():
|
||||
"Load a default font."
|
||||
from StringIO import StringIO
|
||||
from io import BytesIO
|
||||
import base64
|
||||
f = ImageFont()
|
||||
f._load_pilfont_data(
|
||||
# courB08
|
||||
StringIO(base64.decodestring('''
|
||||
BytesIO(base64.decodestring(b'''
|
||||
UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
|
@ -350,7 +352,7 @@ AJsAEQAGAAAAAP/6AAX//wCbAAoAoAAPAAYAAAAA//oABQABAKAACgClABEABgAA////+AAGAAAA
|
|||
pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG
|
||||
AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA////
|
||||
+QAGAAIAzgAKANUAEw==
|
||||
''')), Image.open(StringIO(base64.decodestring('''
|
||||
''')), Image.open(BytesIO(base64.decodestring(b'''
|
||||
iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u
|
||||
Mc4b7vuds/xzjz5/3/7u/n9vMe7vnfH/9++vPn/xyf5zhxzjt8GHw8+2d83u8x27199/nxuQ6Od9
|
||||
M43/5z2I+9n9ZtmDBwMQECDRQw/eQIQohJXxpBCNVE6QCCAAAAD//wBlAJr/AgALyj1t/wINwq0g
|
||||
|
@ -381,10 +383,10 @@ if __name__ == "__main__":
|
|||
# create font data chunk for embedding
|
||||
import base64, os, sys
|
||||
font = "../Images/courB08"
|
||||
print " f._load_pilfont_data("
|
||||
print " # %s" % os.path.basename(font)
|
||||
print " StringIO(base64.decodestring('''"
|
||||
print(" f._load_pilfont_data(")
|
||||
print(" # %s" % os.path.basename(font))
|
||||
print(" BytesIO(base64.decodestring(b'''")
|
||||
base64.encode(open(font + ".pil", "rb"), sys.stdout)
|
||||
print "''')), Image.open(StringIO(base64.decodestring('''"
|
||||
print("''')), Image.open(BytesIO(base64.decodestring(b'''")
|
||||
base64.encode(open(font + ".pbm", "rb"), sys.stdout)
|
||||
print "'''))))"
|
||||
print("'''))))")
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
from . import Image
|
||||
|
||||
##
|
||||
# (New in 1.1.3) The <b>ImageGrab</b> module can be used to copy
|
||||
|
@ -45,7 +45,7 @@ except AttributeError:
|
|||
|
||||
def grab(bbox=None):
|
||||
size, data = grabber()
|
||||
im = Image.fromstring(
|
||||
im = Image.frombytes(
|
||||
"RGB", size, data,
|
||||
# RGB, 32-bit line padding, origo in lower left corner
|
||||
"raw", "BGR", (size[0]*3 + 3) & -4, -1
|
||||
|
@ -65,7 +65,8 @@ def grab(bbox=None):
|
|||
def grabclipboard():
|
||||
debug = 0 # temporary interface
|
||||
data = Image.core.grabclipboard(debug)
|
||||
if Image.isStringType(data):
|
||||
import BmpImagePlugin, StringIO
|
||||
return BmpImagePlugin.DibImageFile(StringIO.StringIO(data))
|
||||
if isinstance(data, bytes):
|
||||
from . import BmpImagePlugin
|
||||
import io
|
||||
return BmpImagePlugin.DibImageFile(io.BytesIO(data))
|
||||
return data
|
||||
|
|
|
@ -15,13 +15,20 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
from . import Image
|
||||
import _imagingmath
|
||||
import sys
|
||||
|
||||
try:
|
||||
import builtins
|
||||
except ImportError:
|
||||
import __builtin__
|
||||
builtins = __builtin__
|
||||
|
||||
VERBOSE = 0
|
||||
|
||||
def _isconstant(v):
|
||||
return isinstance(v, type(0)) or isinstance(v, type(0.0))
|
||||
return isinstance(v, int) or isinstance(v, float)
|
||||
|
||||
class _Operand:
|
||||
# wraps an image operand, providing standard operators
|
||||
|
@ -38,7 +45,7 @@ class _Operand:
|
|||
elif im1.im.mode in ("I", "F"):
|
||||
return im1.im
|
||||
else:
|
||||
raise ValueError, "unsupported mode: %s" % im1.im.mode
|
||||
raise ValueError("unsupported mode: %s" % im1.im.mode)
|
||||
else:
|
||||
# argument was a constant
|
||||
if _isconstant(im1) and self.im.mode in ("1", "L", "I"):
|
||||
|
@ -55,7 +62,7 @@ class _Operand:
|
|||
try:
|
||||
op = getattr(_imagingmath, op+"_"+im1.mode)
|
||||
except AttributeError:
|
||||
raise TypeError, "bad operand type for '%s'" % op
|
||||
raise TypeError("bad operand type for '%s'" % op)
|
||||
_imagingmath.unop(op, out.im.id, im1.im.id)
|
||||
else:
|
||||
# binary operation
|
||||
|
@ -65,7 +72,7 @@ class _Operand:
|
|||
if im1.mode != "F": im1 = im1.convert("F")
|
||||
if im2.mode != "F": im2 = im2.convert("F")
|
||||
if im1.mode != im2.mode:
|
||||
raise ValueError, "mode mismatch"
|
||||
raise ValueError("mode mismatch")
|
||||
if im1.size != im2.size:
|
||||
# crop both arguments to a common size
|
||||
size = (min(im1.size[0], im2.size[0]),
|
||||
|
@ -79,14 +86,20 @@ class _Operand:
|
|||
try:
|
||||
op = getattr(_imagingmath, op+"_"+im1.mode)
|
||||
except AttributeError:
|
||||
raise TypeError, "bad operand type for '%s'" % op
|
||||
raise TypeError("bad operand type for '%s'" % op)
|
||||
_imagingmath.binop(op, out.im.id, im1.im.id, im2.im.id)
|
||||
return _Operand(out)
|
||||
|
||||
# unary operators
|
||||
def __nonzero__(self):
|
||||
def __bool__(self):
|
||||
# an image is "true" if it contains at least one non-zero pixel
|
||||
return self.im.getbbox() is not None
|
||||
|
||||
if bytes is str:
|
||||
# Provide __nonzero__ for pre-Py3k
|
||||
__nonzero__ = __bool__
|
||||
del __bool__
|
||||
|
||||
def __abs__(self):
|
||||
return self.apply("abs", self)
|
||||
def __pos__(self):
|
||||
|
@ -107,9 +120,9 @@ class _Operand:
|
|||
return self.apply("mul", self, other)
|
||||
def __rmul__(self, other):
|
||||
return self.apply("mul", other, self)
|
||||
def __div__(self, other):
|
||||
def __truediv__(self, other):
|
||||
return self.apply("div", self, other)
|
||||
def __rdiv__(self, other):
|
||||
def __rtruediv__(self, other):
|
||||
return self.apply("div", other, self)
|
||||
def __mod__(self, other):
|
||||
return self.apply("mod", self, other)
|
||||
|
@ -120,6 +133,13 @@ class _Operand:
|
|||
def __rpow__(self, other):
|
||||
return self.apply("pow", other, self)
|
||||
|
||||
if bytes is str:
|
||||
# Provide __div__ and __rdiv__ for pre-Py3k
|
||||
__div__ = __truediv__
|
||||
__rdiv__ = __rtruediv__
|
||||
del __truediv__
|
||||
del __rtruediv__
|
||||
|
||||
# bitwise
|
||||
def __invert__(self):
|
||||
return self.apply("invert", self)
|
||||
|
@ -175,7 +195,7 @@ def imagemath_convert(self, mode):
|
|||
return _Operand(self.im.convert(mode))
|
||||
|
||||
ops = {}
|
||||
for k, v in globals().items():
|
||||
for k, v in list(globals().items()):
|
||||
if k[:10] == "imagemath_":
|
||||
ops[k[10:]] = v
|
||||
|
||||
|
@ -195,12 +215,11 @@ def eval(expression, _dict={}, **kw):
|
|||
args = ops.copy()
|
||||
args.update(_dict)
|
||||
args.update(kw)
|
||||
for k, v in args.items():
|
||||
for k, v in list(args.items()):
|
||||
if hasattr(v, "im"):
|
||||
args[k] = _Operand(v)
|
||||
|
||||
import __builtin__
|
||||
out =__builtin__.eval(expression, args)
|
||||
out = builtins.eval(expression, args)
|
||||
try:
|
||||
return out.im
|
||||
except AttributeError:
|
||||
|
|
|
@ -36,7 +36,7 @@ class ModeDescriptor:
|
|||
def getmode(mode):
|
||||
if not _modes:
|
||||
# initialize mode cache
|
||||
import Image
|
||||
from . import Image
|
||||
# core modes
|
||||
for m, (basemode, basetype, bands) in Image._MODEINFO.items():
|
||||
_modes[m] = ModeDescriptor(m, bands, basemode, basetype)
|
||||
|
|
|
@ -17,8 +17,9 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
from . import Image
|
||||
import operator
|
||||
from functools import reduce
|
||||
|
||||
##
|
||||
# (New in 1.1.3) The <b>ImageOps</b> module contains a number of
|
||||
|
@ -32,7 +33,7 @@ import operator
|
|||
# helpers
|
||||
|
||||
def _border(border):
|
||||
if type(border) is type(()):
|
||||
if isinstance(border, tuple):
|
||||
if len(border) == 2:
|
||||
left, top = right, bottom = border
|
||||
elif len(border) == 4:
|
||||
|
@ -43,7 +44,7 @@ def _border(border):
|
|||
|
||||
def _color(color, mode):
|
||||
if Image.isStringType(color):
|
||||
import ImageColor
|
||||
from . import ImageColor
|
||||
color = ImageColor.getcolor(color, mode)
|
||||
return color
|
||||
|
||||
|
@ -56,7 +57,7 @@ def _lut(image, lut):
|
|||
lut = lut + lut + lut
|
||||
return image.point(lut)
|
||||
else:
|
||||
raise IOError, "not supported for this image mode"
|
||||
raise IOError("not supported for this image mode")
|
||||
|
||||
#
|
||||
# actions
|
||||
|
@ -94,7 +95,7 @@ def autocontrast(image, cutoff=0, ignore=None):
|
|||
for ix in range(256):
|
||||
n = n + h[ix]
|
||||
# remove cutoff% pixels from the low end
|
||||
cut = n * cutoff / 100
|
||||
cut = n * cutoff // 100
|
||||
for lo in range(256):
|
||||
if cut > h[lo]:
|
||||
cut = cut - h[lo]
|
||||
|
@ -105,7 +106,7 @@ def autocontrast(image, cutoff=0, ignore=None):
|
|||
if cut <= 0:
|
||||
break
|
||||
# remove cutoff% samples from the hi end
|
||||
cut = n * cutoff / 100
|
||||
cut = n * cutoff // 100
|
||||
for hi in range(255, -1, -1):
|
||||
if cut > h[hi]:
|
||||
cut = cut - h[hi]
|
||||
|
@ -124,7 +125,7 @@ def autocontrast(image, cutoff=0, ignore=None):
|
|||
break
|
||||
if hi <= lo:
|
||||
# don't bother
|
||||
lut.extend(range(256))
|
||||
lut.extend(list(range(256)))
|
||||
else:
|
||||
scale = 255.0 / (hi - lo)
|
||||
offset = -lo * scale
|
||||
|
@ -155,9 +156,9 @@ def colorize(image, black, white):
|
|||
white = _color(white, "RGB")
|
||||
red = []; green = []; blue = []
|
||||
for i in range(256):
|
||||
red.append(black[0]+i*(white[0]-black[0])/255)
|
||||
green.append(black[1]+i*(white[1]-black[1])/255)
|
||||
blue.append(black[2]+i*(white[2]-black[2])/255)
|
||||
red.append(black[0]+i*(white[0]-black[0])//255)
|
||||
green.append(black[1]+i*(white[1]-black[1])//255)
|
||||
blue.append(black[2]+i*(white[2]-black[2])//255)
|
||||
image = image.convert("RGB")
|
||||
return _lut(image, red + green + blue)
|
||||
|
||||
|
@ -209,17 +210,17 @@ def equalize(image, mask=None):
|
|||
h = image.histogram(mask)
|
||||
lut = []
|
||||
for b in range(0, len(h), 256):
|
||||
histo = filter(None, h[b:b+256])
|
||||
histo = [_f for _f in h[b:b+256] if _f]
|
||||
if len(histo) <= 1:
|
||||
lut.extend(range(256))
|
||||
lut.extend(list(range(256)))
|
||||
else:
|
||||
step = (reduce(operator.add, histo) - histo[-1]) / 255
|
||||
step = (reduce(operator.add, histo) - histo[-1]) // 255
|
||||
if not step:
|
||||
lut.extend(range(256))
|
||||
lut.extend(list(range(256)))
|
||||
else:
|
||||
n = step / 2
|
||||
n = step // 2
|
||||
for i in range(256):
|
||||
lut.append(n / step)
|
||||
lut.append(n // step)
|
||||
n = n + h[i+b]
|
||||
return _lut(image, lut)
|
||||
|
||||
|
@ -274,7 +275,7 @@ def fit(image, size, method=Image.NEAREST, bleed=0.0, centering=(0.5, 0.5)):
|
|||
# http://www.cazabon.com
|
||||
|
||||
# ensure inputs are valid
|
||||
if type(centering) != type([]):
|
||||
if not isinstance(centering, list):
|
||||
centering = [centering[0], centering[1]]
|
||||
|
||||
if centering[0] > 1.0 or centering[0] < 0.0:
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#
|
||||
|
||||
import array
|
||||
import Image, ImageColor
|
||||
from . import Image, ImageColor
|
||||
|
||||
##
|
||||
# Colour palette wrapper for palette mapped images.
|
||||
|
@ -28,38 +28,42 @@ class ImagePalette:
|
|||
def __init__(self, mode = "RGB", palette = None):
|
||||
self.mode = mode
|
||||
self.rawmode = None # if set, palette contains raw data
|
||||
self.palette = palette or range(256)*len(self.mode)
|
||||
self.palette = palette or list(range(256))*len(self.mode)
|
||||
self.colors = {}
|
||||
self.dirty = None
|
||||
if len(self.mode)*256 != len(self.palette):
|
||||
raise ValueError, "wrong palette size"
|
||||
raise ValueError("wrong palette size")
|
||||
|
||||
def getdata(self):
|
||||
# experimental: get palette contents in format suitable
|
||||
# for the low-level im.putpalette primitive
|
||||
if self.rawmode:
|
||||
return self.rawmode, self.palette
|
||||
return self.mode + ";L", self.tostring()
|
||||
return self.mode + ";L", self.tobytes()
|
||||
|
||||
def tostring(self):
|
||||
# experimental: convert palette to string
|
||||
def tobytes(self):
|
||||
# experimental: convert palette to bytes
|
||||
if self.rawmode:
|
||||
raise ValueError("palette contains raw palette data")
|
||||
if Image.isStringType(self.palette):
|
||||
if isinstance(self.palette, bytes):
|
||||
return self.palette
|
||||
return array.array("B", self.palette).tostring()
|
||||
|
||||
if bytes is str:
|
||||
# Declare tostring as an alias for tobytes
|
||||
tostring = tobytes
|
||||
|
||||
def getcolor(self, color):
|
||||
# experimental: given an rgb tuple, allocate palette entry
|
||||
if self.rawmode:
|
||||
raise ValueError("palette contains raw palette data")
|
||||
if Image.isTupleType(color):
|
||||
if isinstance(color, tuple):
|
||||
try:
|
||||
return self.colors[color]
|
||||
except KeyError:
|
||||
# allocate new color slot
|
||||
if Image.isStringType(self.palette):
|
||||
self.palette = map(int, self.palette)
|
||||
if isinstance(self.palette, bytes):
|
||||
self.palette = [int(x) for x in self.palette]
|
||||
index = len(self.colors)
|
||||
if index >= 256:
|
||||
raise ValueError("cannot allocate more than 256 colors")
|
||||
|
@ -76,7 +80,7 @@ class ImagePalette:
|
|||
# (experimental) save palette to text file
|
||||
if self.rawmode:
|
||||
raise ValueError("palette contains raw palette data")
|
||||
if type(fp) == type(""):
|
||||
if isinstance(fp, str):
|
||||
fp = open(fp, "w")
|
||||
fp.write("# Palette\n")
|
||||
fp.write("# Mode: %s\n" % self.mode)
|
||||
|
@ -104,7 +108,7 @@ def _make_linear_lut(black, white):
|
|||
lut = []
|
||||
if black == 0:
|
||||
for i in range(256):
|
||||
lut.append(white*i/255)
|
||||
lut.append(white*i//255)
|
||||
else:
|
||||
raise NotImplementedError # FIXME
|
||||
return lut
|
||||
|
@ -119,7 +123,7 @@ def new(mode, data):
|
|||
return Image.core.new_palette(mode, data)
|
||||
|
||||
def negative(mode="RGB"):
|
||||
palette = range(256)
|
||||
palette = list(range(256))
|
||||
palette.reverse()
|
||||
return ImagePalette(mode, palette * len(mode))
|
||||
|
||||
|
@ -138,7 +142,7 @@ def sepia(white="#fff0c0"):
|
|||
return ImagePalette("RGB", r + g + b)
|
||||
|
||||
def wedge(mode="RGB"):
|
||||
return ImagePalette(mode, range(256) * len(mode))
|
||||
return ImagePalette(mode, list(range(256)) * len(mode))
|
||||
|
||||
def load(filename):
|
||||
|
||||
|
@ -150,33 +154,39 @@ def load(filename):
|
|||
|
||||
if not lut:
|
||||
try:
|
||||
import GimpPaletteFile
|
||||
from . import GimpPaletteFile
|
||||
fp.seek(0)
|
||||
p = GimpPaletteFile.GimpPaletteFile(fp)
|
||||
lut = p.getpalette()
|
||||
except (SyntaxError, ValueError):
|
||||
#import traceback
|
||||
#traceback.print_exc()
|
||||
pass
|
||||
|
||||
if not lut:
|
||||
try:
|
||||
import GimpGradientFile
|
||||
from . import GimpGradientFile
|
||||
fp.seek(0)
|
||||
p = GimpGradientFile.GimpGradientFile(fp)
|
||||
lut = p.getpalette()
|
||||
except (SyntaxError, ValueError):
|
||||
#import traceback
|
||||
#traceback.print_exc()
|
||||
pass
|
||||
|
||||
if not lut:
|
||||
try:
|
||||
import PaletteFile
|
||||
from . import PaletteFile
|
||||
fp.seek(0)
|
||||
p = PaletteFile.PaletteFile(fp)
|
||||
lut = p.getpalette()
|
||||
except (SyntaxError, ValueError):
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
pass
|
||||
|
||||
if not lut:
|
||||
raise IOError, "cannot load palette"
|
||||
raise IOError("cannot load palette")
|
||||
|
||||
return lut # data, rawmode
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
from . import Image
|
||||
|
||||
##
|
||||
# Path wrapper.
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
from . import Image
|
||||
|
||||
from PyQt4.QtGui import QImage, qRgb
|
||||
|
||||
|
@ -62,11 +62,11 @@ class ImageQt(QImage):
|
|||
for i in range(0, len(palette), 3):
|
||||
colortable.append(rgb(*palette[i:i+3]))
|
||||
elif im.mode == "RGB":
|
||||
data = im.tostring("raw", "BGRX")
|
||||
data = im.tobytes("raw", "BGRX")
|
||||
format = QImage.Format_RGB32
|
||||
elif im.mode == "RGBA":
|
||||
try:
|
||||
data = im.tostring("raw", "BGRA")
|
||||
data = im.tobytes("raw", "BGRA")
|
||||
except SystemError:
|
||||
# workaround for earlier versions
|
||||
r, g, b, a = im.split()
|
||||
|
@ -76,7 +76,7 @@ class ImageQt(QImage):
|
|||
raise ValueError("unsupported image mode %r" % im.mode)
|
||||
|
||||
# must keep a reference, or Qt will crash!
|
||||
self.__data = data or im.tostring()
|
||||
self.__data = data or im.tobytes()
|
||||
|
||||
QImage.__init__(self, self.__data, im.size[0], im.size[1], format)
|
||||
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
from __future__ import print_function
|
||||
|
||||
from . import Image
|
||||
import os, sys
|
||||
|
||||
_viewers = []
|
||||
|
@ -160,4 +162,4 @@ else:
|
|||
|
||||
if __name__ == "__main__":
|
||||
# usage: python ImageShow.py imagefile [title]
|
||||
print show(Image.open(sys.argv[1]), *sys.argv[2:])
|
||||
print(show(Image.open(sys.argv[1]), *sys.argv[2:]))
|
||||
|
|
|
@ -21,8 +21,9 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
from . import Image
|
||||
import operator, math
|
||||
from functools import reduce
|
||||
|
||||
##
|
||||
# The <b>ImageStat</b> module calculates global statistics for an
|
||||
|
@ -52,14 +53,14 @@ class Stat:
|
|||
self.h = image_or_list.histogram()
|
||||
except AttributeError:
|
||||
self.h = image_or_list # assume it to be a histogram list
|
||||
if type(self.h) != type([]):
|
||||
raise TypeError, "first argument must be image or list"
|
||||
self.bands = range(len(self.h) / 256)
|
||||
if not isinstance(self.h, list):
|
||||
raise TypeError("first argument must be image or list")
|
||||
self.bands = list(range(len(self.h) // 256))
|
||||
|
||||
def __getattr__(self, id):
|
||||
"Calculate missing attribute"
|
||||
if id[:4] == "_get":
|
||||
raise AttributeError, id
|
||||
raise AttributeError(id)
|
||||
# calculate missing attribute
|
||||
v = getattr(self, "_get" + id)()
|
||||
setattr(self, id, v)
|
||||
|
@ -126,7 +127,7 @@ class Stat:
|
|||
v = []
|
||||
for i in self.bands:
|
||||
s = 0
|
||||
l = self.count[i]/2
|
||||
l = self.count[i]//2
|
||||
b = i * 256
|
||||
for j in range(256):
|
||||
s = s + self.h[b+j]
|
||||
|
|
|
@ -25,7 +25,14 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Tkinter, Image
|
||||
try:
|
||||
import tkinter
|
||||
except ImportError:
|
||||
import Tkinter
|
||||
tkinter = Tkinter
|
||||
del Tkinter
|
||||
|
||||
from . import Image
|
||||
|
||||
##
|
||||
# The <b>ImageTk</b> module contains support to create and modify
|
||||
|
@ -45,9 +52,9 @@ def _pilbitmap_check():
|
|||
if _pilbitmap_ok is None:
|
||||
try:
|
||||
im = Image.new("1", (1,1))
|
||||
Tkinter.BitmapImage(data="PIL:%d" % im.im.id)
|
||||
tkinter.BitmapImage(data="PIL:%d" % im.im.id)
|
||||
_pilbitmap_ok = 1
|
||||
except Tkinter.TclError:
|
||||
except tkinter.TclError:
|
||||
_pilbitmap_ok = 0
|
||||
return _pilbitmap_ok
|
||||
|
||||
|
@ -81,12 +88,12 @@ class PhotoImage:
|
|||
|
||||
# Tk compatibility: file or data
|
||||
if image is None:
|
||||
if kw.has_key("file"):
|
||||
if "file" in kw:
|
||||
image = Image.open(kw["file"])
|
||||
del kw["file"]
|
||||
elif kw.has_key("data"):
|
||||
from StringIO import StringIO
|
||||
image = Image.open(StringIO(kw["data"]))
|
||||
elif "data" in kw:
|
||||
from io import BytesIO
|
||||
image = Image.open(BytesIO(kw["data"]))
|
||||
del kw["data"]
|
||||
|
||||
if hasattr(image, "mode") and hasattr(image, "size"):
|
||||
|
@ -110,7 +117,7 @@ class PhotoImage:
|
|||
|
||||
self.__mode = mode
|
||||
self.__size = size
|
||||
self.__photo = apply(Tkinter.PhotoImage, (), kw)
|
||||
self.__photo = tkinter.PhotoImage(**kw)
|
||||
self.tk = self.__photo.tk
|
||||
if image:
|
||||
self.paste(image)
|
||||
|
@ -175,7 +182,7 @@ class PhotoImage:
|
|||
|
||||
try:
|
||||
tk.call("PyImagingPhoto", self.__photo, block.id)
|
||||
except Tkinter.TclError, v:
|
||||
except tkinter.TclError as v:
|
||||
# activate Tkinter hook
|
||||
try:
|
||||
import _imagingtk
|
||||
|
@ -184,7 +191,7 @@ class PhotoImage:
|
|||
except AttributeError:
|
||||
_imagingtk.tkinit(id(tk), 0)
|
||||
tk.call("PyImagingPhoto", self.__photo, block.id)
|
||||
except (ImportError, AttributeError, Tkinter.TclError):
|
||||
except (ImportError, AttributeError, tkinter.TclError):
|
||||
raise # configuration problem; cannot attach to Tkinter
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -213,12 +220,12 @@ class BitmapImage:
|
|||
|
||||
# Tk compatibility: file or data
|
||||
if image is None:
|
||||
if kw.has_key("file"):
|
||||
if "file" in kw:
|
||||
image = Image.open(kw["file"])
|
||||
del kw["file"]
|
||||
elif kw.has_key("data"):
|
||||
from StringIO import StringIO
|
||||
image = Image.open(StringIO(kw["data"]))
|
||||
elif "data" in kw:
|
||||
from io import BytesIO
|
||||
image = Image.open(BytesIO(kw["data"]))
|
||||
del kw["data"]
|
||||
|
||||
self.__mode = image.mode
|
||||
|
@ -232,7 +239,7 @@ class BitmapImage:
|
|||
else:
|
||||
# slow but safe way
|
||||
kw["data"] = image.tobitmap()
|
||||
self.__photo = apply(Tkinter.BitmapImage, (), kw)
|
||||
self.__photo = tkinter.BitmapImage(**kw)
|
||||
|
||||
def __del__(self):
|
||||
name = self.__photo.name
|
||||
|
@ -279,18 +286,18 @@ def getimage(photo):
|
|||
|
||||
def _show(image, title):
|
||||
|
||||
class UI(Tkinter.Label):
|
||||
class UI(tkinter.Label):
|
||||
def __init__(self, master, im):
|
||||
if im.mode == "1":
|
||||
self.image = BitmapImage(im, foreground="white", master=master)
|
||||
else:
|
||||
self.image = PhotoImage(im, master=master)
|
||||
Tkinter.Label.__init__(self, master, image=self.image,
|
||||
tkinter.Label.__init__(self, master, image=self.image,
|
||||
bg="black", bd=0)
|
||||
|
||||
if not Tkinter._default_root:
|
||||
raise IOError, "tkinter not initialized"
|
||||
top = Tkinter.Toplevel()
|
||||
if not tkinter._default_root:
|
||||
raise IOError("tkinter not initialized")
|
||||
top = tkinter.Toplevel()
|
||||
if title:
|
||||
top.title(title)
|
||||
UI(top, image).pack()
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
from . import Image
|
||||
|
||||
class Transform(Image.ImageTransformHandler):
|
||||
def __init__(self, data):
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
from . import Image
|
||||
|
||||
##
|
||||
# The <b>ImageWin</b> module contains support to create and display
|
||||
|
@ -151,22 +151,25 @@ class Dib:
|
|||
self.image.paste(im.im)
|
||||
|
||||
##
|
||||
# Load display memory contents from string buffer.
|
||||
# Load display memory contents from byte data.
|
||||
#
|
||||
# @param buffer A string buffer containing display data (usually
|
||||
# data returned from <b>tostring</b>)
|
||||
# @param buffer A buffer containing display data (usually
|
||||
# data returned from <b>tobytes</b>)
|
||||
|
||||
def fromstring(self, buffer):
|
||||
return self.image.fromstring(buffer)
|
||||
def frombytes(self, buffer):
|
||||
return self.image.frombytes(buffer)
|
||||
|
||||
##
|
||||
# Copy display memory contents to string buffer.
|
||||
# Copy display memory contents to bytes object.
|
||||
#
|
||||
# @return A string buffer containing display data.
|
||||
# @return A bytes object containing display data.
|
||||
|
||||
def tostring(self):
|
||||
return self.image.tostring()
|
||||
def tobytes(self):
|
||||
return self.image.tobytes()
|
||||
|
||||
if bytes is str:
|
||||
tostring = tobytes
|
||||
fromstring = frombytes
|
||||
|
||||
##
|
||||
# Create a Window with the given title size.
|
||||
|
@ -179,7 +182,7 @@ class Window:
|
|||
)
|
||||
|
||||
def __dispatcher(self, action, *args):
|
||||
return apply(getattr(self, "ui_handle_" + action), args)
|
||||
return getattr(self, "ui_handle_" + action)(*args)
|
||||
|
||||
def ui_handle_clear(self, dc, x0, y0, x1, y1):
|
||||
pass
|
||||
|
|
|
@ -19,12 +19,12 @@ __version__ = "0.2"
|
|||
|
||||
import re
|
||||
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
field = re.compile(r"([a-z]*) ([^ \r\n]*)")
|
||||
field = re.compile(br"([a-z]*) ([^ \r\n]*)")
|
||||
|
||||
##
|
||||
# Image plugin for IM Tools images.
|
||||
|
@ -39,19 +39,19 @@ class ImtImageFile(ImageFile.ImageFile):
|
|||
# Quick rejection: if there's not a LF among the first
|
||||
# 100 bytes, this is (probably) not a text header.
|
||||
|
||||
if not "\n" in self.fp.read(100):
|
||||
raise SyntaxError, "not an IM file"
|
||||
if not b"\n" in self.fp.read(100):
|
||||
raise SyntaxError("not an IM file")
|
||||
self.fp.seek(0)
|
||||
|
||||
xsize = ysize = 0
|
||||
|
||||
while 1:
|
||||
while True:
|
||||
|
||||
s = self.fp.read(1)
|
||||
if not s:
|
||||
break
|
||||
|
||||
if s == chr(12):
|
||||
if s == b'\x0C':
|
||||
|
||||
# image data begins
|
||||
self.tile = [("raw", (0,0)+self.size,
|
||||
|
@ -67,7 +67,7 @@ class ImtImageFile(ImageFile.ImageFile):
|
|||
s = s + self.fp.readline()
|
||||
if len(s) == 1 or len(s) > 100:
|
||||
break
|
||||
if s[0] == "*":
|
||||
if s[0] == b"*":
|
||||
continue # comment
|
||||
|
||||
m = field.match(s)
|
||||
|
|
|
@ -15,37 +15,36 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
__version__ = "0.3"
|
||||
|
||||
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
import os, tempfile
|
||||
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16be
|
||||
i32 = _binary.i32be
|
||||
o8 = _binary.o8
|
||||
|
||||
COMPRESSION = {
|
||||
1: "raw",
|
||||
5: "jpeg"
|
||||
}
|
||||
|
||||
PAD = chr(0) * 4
|
||||
PAD = o8(0) * 4
|
||||
|
||||
#
|
||||
# Helpers
|
||||
|
||||
def i16(c):
|
||||
return ord(c[1]) + (ord(c[0])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
|
||||
|
||||
def i(c):
|
||||
return i32((PAD + c)[-4:])
|
||||
|
||||
def dump(c):
|
||||
for i in c:
|
||||
print "%02x" % ord(i),
|
||||
print
|
||||
print("%02x" % i8(i), end=' ')
|
||||
print()
|
||||
|
||||
##
|
||||
# Image plugin for IPTC/NAA datastreams. To read IPTC/NAA fields
|
||||
|
@ -66,16 +65,16 @@ class IptcImageFile(ImageFile.ImageFile):
|
|||
if not len(s):
|
||||
return None, 0
|
||||
|
||||
tag = ord(s[1]), ord(s[2])
|
||||
tag = i8(s[1]), i8(s[2])
|
||||
|
||||
# syntax
|
||||
if ord(s[0]) != 0x1C or tag[0] < 1 or tag[0] > 9:
|
||||
raise SyntaxError, "invalid IPTC/NAA file"
|
||||
if i8(s[0]) != 0x1C or tag[0] < 1 or tag[0] > 9:
|
||||
raise SyntaxError("invalid IPTC/NAA file")
|
||||
|
||||
# field size
|
||||
size = ord(s[3])
|
||||
size = i8(s[3])
|
||||
if size > 132:
|
||||
raise IOError, "illegal field length in IPTC/NAA file"
|
||||
raise IOError("illegal field length in IPTC/NAA file")
|
||||
elif size == 128:
|
||||
size = 0
|
||||
elif size > 128:
|
||||
|
@ -97,7 +96,7 @@ class IptcImageFile(ImageFile.ImageFile):
|
|||
if sz != size[0]:
|
||||
return 0
|
||||
y = 1
|
||||
while 1:
|
||||
while True:
|
||||
self.fp.seek(sz, 1)
|
||||
t, s = self.field()
|
||||
if t != (8, 10):
|
||||
|
@ -110,7 +109,7 @@ class IptcImageFile(ImageFile.ImageFile):
|
|||
def _open(self):
|
||||
|
||||
# load descriptive fields
|
||||
while 1:
|
||||
while True:
|
||||
offset = self.fp.tell()
|
||||
tag, size = self.field()
|
||||
if not tag or tag == (8,10):
|
||||
|
@ -119,7 +118,7 @@ class IptcImageFile(ImageFile.ImageFile):
|
|||
tagdata = self.fp.read(size)
|
||||
else:
|
||||
tagdata = None
|
||||
if tag in self.info.keys():
|
||||
if tag in list(self.info.keys()):
|
||||
if isinstance(self.info[tag], list):
|
||||
self.info[tag].append(tagdata)
|
||||
else:
|
||||
|
@ -130,10 +129,10 @@ class IptcImageFile(ImageFile.ImageFile):
|
|||
# print tag, self.info[tag]
|
||||
|
||||
# mode
|
||||
layers = ord(self.info[(3,60)][0])
|
||||
component = ord(self.info[(3,60)][1])
|
||||
if self.info.has_key((3,65)):
|
||||
id = ord(self.info[(3,65)][0])-1
|
||||
layers = i8(self.info[(3,60)][0])
|
||||
component = i8(self.info[(3,60)][1])
|
||||
if (3,65) in self.info:
|
||||
id = i8(self.info[(3,65)][0])-1
|
||||
else:
|
||||
id = 0
|
||||
if layers == 1 and not component:
|
||||
|
@ -150,7 +149,7 @@ class IptcImageFile(ImageFile.ImageFile):
|
|||
try:
|
||||
compression = COMPRESSION[self.getint((3,120))]
|
||||
except KeyError:
|
||||
raise IOError, "Unknown IPTC image compression"
|
||||
raise IOError("Unknown IPTC image compression")
|
||||
|
||||
# tile
|
||||
if tag == (8,10):
|
||||
|
@ -179,7 +178,7 @@ class IptcImageFile(ImageFile.ImageFile):
|
|||
# To simplify access to the extracted file,
|
||||
# prepend a PPM header
|
||||
o.write("P5\n%d %d\n255\n" % self.size)
|
||||
while 1:
|
||||
while True:
|
||||
type, size = self.field()
|
||||
if type != (8, 10):
|
||||
break
|
||||
|
@ -218,8 +217,8 @@ Image.register_extension("IPTC", ".iim")
|
|||
|
||||
def getiptcinfo(im):
|
||||
|
||||
import TiffImagePlugin, JpegImagePlugin
|
||||
import StringIO
|
||||
from . import TiffImagePlugin, JpegImagePlugin
|
||||
import io
|
||||
|
||||
data = None
|
||||
|
||||
|
@ -241,7 +240,7 @@ def getiptcinfo(im):
|
|||
code = JpegImagePlugin.i16(app, offset)
|
||||
offset = offset + 2
|
||||
# resource name (usually empty)
|
||||
name_len = ord(app[offset])
|
||||
name_len = i8(app[offset])
|
||||
name = app[offset+1:offset+1+name_len]
|
||||
offset = 1 + offset + name_len
|
||||
if offset & 1:
|
||||
|
@ -278,7 +277,7 @@ def getiptcinfo(im):
|
|||
|
||||
# parse the IPTC information chunk
|
||||
im.info = {}
|
||||
im.fp = StringIO.StringIO(data)
|
||||
im.fp = io.BytesIO(data)
|
||||
|
||||
try:
|
||||
im._open()
|
||||
|
|
|
@ -35,14 +35,12 @@
|
|||
__version__ = "0.6"
|
||||
|
||||
import array, struct
|
||||
import string
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
def i16(c,o=0):
|
||||
return ord(c[o+1]) + (ord(c[o])<<8)
|
||||
|
||||
def i32(c,o=0):
|
||||
return ord(c[o+3]) + (ord(c[o+2])<<8) + (ord(c[o+1])<<16) + (ord(c[o])<<24)
|
||||
i8 = _binary.i8
|
||||
o8 = _binary.o8
|
||||
i16 = _binary.i16be
|
||||
i32 = _binary.i32be
|
||||
|
||||
#
|
||||
# Parser
|
||||
|
@ -64,13 +62,13 @@ def APP(self, marker):
|
|||
self.app[app] = s # compatibility
|
||||
self.applist.append((app, s))
|
||||
|
||||
if marker == 0xFFE0 and s[:4] == "JFIF":
|
||||
if marker == 0xFFE0 and s[:4] == b"JFIF":
|
||||
# extract JFIF information
|
||||
self.info["jfif"] = version = i16(s, 5) # version
|
||||
self.info["jfif_version"] = divmod(version, 256)
|
||||
# extract JFIF properties
|
||||
try:
|
||||
jfif_unit = ord(s[7])
|
||||
jfif_unit = i8(s[7])
|
||||
jfif_density = i16(s, 8), i16(s, 10)
|
||||
except:
|
||||
pass
|
||||
|
@ -79,13 +77,13 @@ def APP(self, marker):
|
|||
self.info["dpi"] = jfif_density
|
||||
self.info["jfif_unit"] = jfif_unit
|
||||
self.info["jfif_density"] = jfif_density
|
||||
elif marker == 0xFFE1 and s[:5] == "Exif\0":
|
||||
elif marker == 0xFFE1 and s[:5] == b"Exif\0":
|
||||
# extract Exif information (incomplete)
|
||||
self.info["exif"] = s # FIXME: value will change
|
||||
elif marker == 0xFFE2 and s[:5] == "FPXR\0":
|
||||
elif marker == 0xFFE2 and s[:5] == b"FPXR\0":
|
||||
# extract FlashPix information (incomplete)
|
||||
self.info["flashpix"] = s # FIXME: value will change
|
||||
elif marker == 0xFFE2 and s[:12] == "ICC_PROFILE\0":
|
||||
elif marker == 0xFFE2 and s[:12] == b"ICC_PROFILE\0":
|
||||
# Since an ICC profile can be larger than the maximum size of
|
||||
# a JPEG marker (64K), we need provisions to split it into
|
||||
# multiple markers. The format defined by the ICC specifies
|
||||
|
@ -98,11 +96,11 @@ def APP(self, marker):
|
|||
# reassemble the profile, rather than assuming that the APP2
|
||||
# markers appear in the correct sequence.
|
||||
self.icclist.append(s)
|
||||
elif marker == 0xFFEE and s[:5] == "Adobe":
|
||||
elif marker == 0xFFEE and s[:5] == b"Adobe":
|
||||
self.info["adobe"] = i16(s, 5)
|
||||
# extract Adobe custom properties
|
||||
try:
|
||||
adobe_transform = ord(s[1])
|
||||
adobe_transform = i8(s[1])
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
|
@ -130,11 +128,11 @@ def SOF(self, marker):
|
|||
s = ImageFile._safe_read(self.fp, n)
|
||||
self.size = i16(s[3:]), i16(s[1:])
|
||||
|
||||
self.bits = ord(s[0])
|
||||
self.bits = i8(s[0])
|
||||
if self.bits != 8:
|
||||
raise SyntaxError("cannot handle %d-bit layers" % self.bits)
|
||||
|
||||
self.layers = ord(s[5])
|
||||
self.layers = i8(s[5])
|
||||
if self.layers == 1:
|
||||
self.mode = "L"
|
||||
elif self.layers == 3:
|
||||
|
@ -150,11 +148,11 @@ def SOF(self, marker):
|
|||
if self.icclist:
|
||||
# fixup icc profile
|
||||
self.icclist.sort() # sort by sequence number
|
||||
if ord(self.icclist[0][13]) == len(self.icclist):
|
||||
if i8(self.icclist[0][13]) == len(self.icclist):
|
||||
profile = []
|
||||
for p in self.icclist:
|
||||
profile.append(p[14:])
|
||||
icc_profile = string.join(profile, "")
|
||||
icc_profile = b"".join(profile)
|
||||
else:
|
||||
icc_profile = None # wrong number of fragments
|
||||
self.info["icc_profile"] = icc_profile
|
||||
|
@ -163,7 +161,7 @@ def SOF(self, marker):
|
|||
for i in range(6, len(s), 3):
|
||||
t = s[i:i+3]
|
||||
# 4-tuples: id, vsamp, hsamp, qtable
|
||||
self.layer.append((t[0], ord(t[1])/16, ord(t[1])&15, ord(t[2])))
|
||||
self.layer.append((t[0], i8(t[1])//16, i8(t[1])&15, i8(t[2])))
|
||||
|
||||
def DQT(self, marker):
|
||||
#
|
||||
|
@ -179,8 +177,8 @@ def DQT(self, marker):
|
|||
while len(s):
|
||||
if len(s) < 65:
|
||||
raise SyntaxError("bad quantization table marker")
|
||||
v = ord(s[0])
|
||||
if v/16 == 0:
|
||||
v = i8(s[0])
|
||||
if v//16 == 0:
|
||||
self.quantization[v&15] = array.array("b", s[1:65])
|
||||
s = s[65:]
|
||||
else:
|
||||
|
@ -259,7 +257,7 @@ MARKER = {
|
|||
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[0] == "\377"
|
||||
return prefix[0:1] == b"\377"
|
||||
|
||||
##
|
||||
# Image plugin for JPEG and JFIF images.
|
||||
|
@ -273,7 +271,7 @@ class JpegImageFile(ImageFile.ImageFile):
|
|||
|
||||
s = self.fp.read(1)
|
||||
|
||||
if ord(s[0]) != 255:
|
||||
if i8(s[0]) != 255:
|
||||
raise SyntaxError("not a JPEG file")
|
||||
|
||||
# Create attributes
|
||||
|
@ -288,13 +286,13 @@ class JpegImageFile(ImageFile.ImageFile):
|
|||
self.applist = []
|
||||
self.icclist = []
|
||||
|
||||
while 1:
|
||||
while True:
|
||||
|
||||
s = s + self.fp.read(1)
|
||||
|
||||
i = i16(s)
|
||||
|
||||
if MARKER.has_key(i):
|
||||
if i in MARKER:
|
||||
name, description, handler = MARKER[i]
|
||||
# print hex(i), name, description
|
||||
if handler is not None:
|
||||
|
@ -326,12 +324,12 @@ class JpegImageFile(ImageFile.ImageFile):
|
|||
a = mode, ""
|
||||
|
||||
if size:
|
||||
scale = max(self.size[0] / size[0], self.size[1] / size[1])
|
||||
scale = max(self.size[0] // size[0], self.size[1] // size[1])
|
||||
for s in [8, 4, 2, 1]:
|
||||
if scale >= s:
|
||||
break
|
||||
e = e[0], e[1], (e[2]-e[0]+s-1)/s+e[0], (e[3]-e[1]+s-1)/s+e[1]
|
||||
self.size = ((self.size[0]+s-1)/s, (self.size[1]+s-1)/s)
|
||||
e = e[0], e[1], (e[2]-e[0]+s-1)//s+e[0], (e[3]-e[1]+s-1)//s+e[1]
|
||||
self.size = ((self.size[0]+s-1)//s, (self.size[1]+s-1)//s)
|
||||
scale = s
|
||||
|
||||
self.tile = [(d, e, o, a)]
|
||||
|
@ -362,7 +360,8 @@ class JpegImageFile(ImageFile.ImageFile):
|
|||
# Extract EXIF information. This method is highly experimental,
|
||||
# and is likely to be replaced with something better in a future
|
||||
# version.
|
||||
import TiffImagePlugin, StringIO
|
||||
from . import TiffImagePlugin
|
||||
import io
|
||||
def fixup(value):
|
||||
if len(value) == 1:
|
||||
return value[0]
|
||||
|
@ -373,7 +372,7 @@ class JpegImageFile(ImageFile.ImageFile):
|
|||
data = self.info["exif"]
|
||||
except KeyError:
|
||||
return None
|
||||
file = StringIO.StringIO(data[6:])
|
||||
file = io.BytesIO(data[6:])
|
||||
head = file.read(8)
|
||||
exif = {}
|
||||
# process dictionary
|
||||
|
@ -436,7 +435,7 @@ def _save(im, fp, filename):
|
|||
elif subsampling == "4:1:1":
|
||||
subsampling = 2
|
||||
|
||||
extra = ""
|
||||
extra = b""
|
||||
|
||||
icc_profile = info.get("icc_profile")
|
||||
if icc_profile:
|
||||
|
@ -450,7 +449,7 @@ def _save(im, fp, filename):
|
|||
i = 1
|
||||
for marker in markers:
|
||||
size = struct.pack(">H", 2 + ICC_OVERHEAD_LEN + len(marker))
|
||||
extra = extra + ("\xFF\xE2" + size + "ICC_PROFILE\0" + chr(i) + chr(len(markers)) + marker)
|
||||
extra = extra + (b"\xFF\xE2" + size + b"ICC_PROFILE\0" + o8(i) + o8(len(markers)) + marker)
|
||||
i = i + 1
|
||||
|
||||
# get keyword arguments
|
||||
|
@ -459,9 +458,9 @@ def _save(im, fp, filename):
|
|||
# "progressive" is the official name, but older documentation
|
||||
# says "progression"
|
||||
# FIXME: issue a warning if the wrong form is used (post-1.1.7)
|
||||
info.has_key("progressive") or info.has_key("progression"),
|
||||
"progressive" in info or "progression" in info,
|
||||
info.get("smooth", 0),
|
||||
info.has_key("optimize"),
|
||||
"optimize" in info,
|
||||
info.get("streamtype", 0),
|
||||
dpi[0], dpi[1],
|
||||
subsampling,
|
||||
|
|
|
@ -19,10 +19,10 @@
|
|||
__version__ = "0.2"
|
||||
|
||||
import struct
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile
|
||||
|
||||
def _accept(s):
|
||||
return s[:8] == "\x00\x00\x00\x00\x00\x00\x00\x04"
|
||||
return s[:8] == b"\x00\x00\x00\x00\x00\x00\x00\x04"
|
||||
|
||||
##
|
||||
# Image plugin for McIdas area images.
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
__version__ = "0.1"
|
||||
|
||||
|
||||
import Image, TiffImagePlugin
|
||||
from OleFileIO import *
|
||||
from . import Image, TiffImagePlugin
|
||||
from .OleFileIO import *
|
||||
|
||||
|
||||
#
|
||||
|
@ -47,7 +47,7 @@ class MicImageFile(TiffImagePlugin.TiffImageFile):
|
|||
try:
|
||||
self.ole = OleFileIO(self.fp)
|
||||
except IOError:
|
||||
raise SyntaxError, "not an MIC file; invalid OLE file"
|
||||
raise SyntaxError("not an MIC file; invalid OLE file")
|
||||
|
||||
# find ACI subfiles with Image members (maybe not the
|
||||
# best way to identify MIC files, but what the... ;-)
|
||||
|
@ -60,7 +60,7 @@ class MicImageFile(TiffImagePlugin.TiffImageFile):
|
|||
# if we didn't find any images, this is probably not
|
||||
# an MIC file.
|
||||
if not self.images:
|
||||
raise SyntaxError, "not an MIC file; no image entries"
|
||||
raise SyntaxError("not an MIC file; no image entries")
|
||||
|
||||
self.__fp = self.fp
|
||||
self.frame = 0
|
||||
|
@ -75,7 +75,7 @@ class MicImageFile(TiffImagePlugin.TiffImageFile):
|
|||
try:
|
||||
filename = self.images[frame]
|
||||
except IndexError:
|
||||
raise EOFError, "no such frame"
|
||||
raise EOFError("no such frame")
|
||||
|
||||
self.fp = self.ole.openstream(filename)
|
||||
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
|
||||
__version__ = "0.1"
|
||||
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile
|
||||
from ._binary import i8
|
||||
|
||||
#
|
||||
# Bitstream parser
|
||||
|
@ -28,7 +29,7 @@ class BitStream:
|
|||
self.bitbuffer = 0
|
||||
|
||||
def next(self):
|
||||
return ord(self.fp.read(1))
|
||||
return i8(self.fp.read(1))
|
||||
|
||||
def peek(self, bits):
|
||||
while self.bits < bits:
|
||||
|
@ -38,11 +39,11 @@ class BitStream:
|
|||
continue
|
||||
self.bitbuffer = (self.bitbuffer << 8) + c
|
||||
self.bits = self.bits + 8
|
||||
return self.bitbuffer >> (self.bits - bits) & (1L << bits) - 1
|
||||
return self.bitbuffer >> (self.bits - bits) & (1 << bits) - 1
|
||||
|
||||
def skip(self, bits):
|
||||
while self.bits < bits:
|
||||
self.bitbuffer = (self.bitbuffer << 8) + ord(self.fp.read(1))
|
||||
self.bitbuffer = (self.bitbuffer << 8) + i8(self.fp.read(1))
|
||||
self.bits = self.bits + 8
|
||||
self.bits = self.bits - bits
|
||||
|
||||
|
@ -65,7 +66,7 @@ class MpegImageFile(ImageFile.ImageFile):
|
|||
s = BitStream(self.fp)
|
||||
|
||||
if s.read(32) != 0x1B3:
|
||||
raise SyntaxError, "not an MPEG file"
|
||||
raise SyntaxError("not an MPEG file")
|
||||
|
||||
self.mode = "RGB"
|
||||
self.size = s.read(12), s.read(12)
|
||||
|
|
|
@ -19,17 +19,16 @@
|
|||
|
||||
__version__ = "0.1"
|
||||
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
|
||||
#
|
||||
# read MSP files
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
i16 = _binary.i16le
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] in ["DanM", "LinS"]
|
||||
return prefix[:4] in [b"DanM", b"LinS"]
|
||||
|
||||
##
|
||||
# Image plugin for Windows MSP images. This plugin supports both
|
||||
|
@ -44,20 +43,20 @@ class MspImageFile(ImageFile.ImageFile):
|
|||
|
||||
# Header
|
||||
s = self.fp.read(32)
|
||||
if s[:4] not in ["DanM", "LinS"]:
|
||||
raise SyntaxError, "not an MSP file"
|
||||
if s[:4] not in [b"DanM", b"LinS"]:
|
||||
raise SyntaxError("not an MSP file")
|
||||
|
||||
# Header checksum
|
||||
sum = 0
|
||||
for i in range(0, 32, 2):
|
||||
sum = sum ^ i16(s[i:i+2])
|
||||
if sum != 0:
|
||||
raise SyntaxError, "bad MSP checksum"
|
||||
raise SyntaxError("bad MSP checksum")
|
||||
|
||||
self.mode = "1"
|
||||
self.size = i16(s[4:]), i16(s[6:])
|
||||
|
||||
if s[:4] == "DanM":
|
||||
if s[:4] == b"DanM":
|
||||
self.tile = [("raw", (0,0)+self.size, 32, ("1", 0, 1))]
|
||||
else:
|
||||
self.tile = [("msp", (0,0)+self.size, 32+2*self.size[1], None)]
|
||||
|
@ -65,18 +64,17 @@ class MspImageFile(ImageFile.ImageFile):
|
|||
#
|
||||
# write MSP files (uncompressed only)
|
||||
|
||||
def o16(i):
|
||||
return chr(i&255) + chr(i>>8&255)
|
||||
o16 = _binary.o16le
|
||||
|
||||
def _save(im, fp, filename):
|
||||
|
||||
if im.mode != "1":
|
||||
raise IOError, "cannot write mode %s as MSP" % im.mode
|
||||
raise IOError("cannot write mode %s as MSP" % im.mode)
|
||||
|
||||
# create MSP header
|
||||
header = [0] * 16
|
||||
|
||||
header[0], header[1] = i16("Da"), i16("nM") # version 1
|
||||
header[0], header[1] = i16(b"Da"), i16(b"nM") # version 1
|
||||
header[2], header[3] = im.size
|
||||
header[4], header[5] = 1, 1
|
||||
header[6], header[7] = 1, 1
|
||||
|
|
|
@ -36,17 +36,21 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import string, StringIO
|
||||
from __future__ import print_function
|
||||
|
||||
import io
|
||||
import sys
|
||||
from . import _binary
|
||||
|
||||
if str is not bytes:
|
||||
long = int
|
||||
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16le
|
||||
i32 = _binary.i32le
|
||||
|
||||
|
||||
def i16(c, o = 0):
|
||||
return ord(c[o])+(ord(c[o+1])<<8)
|
||||
|
||||
def i32(c, o = 0):
|
||||
return ord(c[o])+(ord(c[o+1])<<8)+(ord(c[o+2])<<16)+(ord(c[o+3])<<24)
|
||||
|
||||
|
||||
MAGIC = '\320\317\021\340\241\261\032\341'
|
||||
MAGIC = b'\320\317\021\340\241\261\032\341'
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -65,7 +69,7 @@ VT_VECTOR=0x1000;
|
|||
# map property id to name (for debugging purposes)
|
||||
|
||||
VT = {}
|
||||
for k, v in vars().items():
|
||||
for k, v in list(vars().items()):
|
||||
if k[:3] == "VT_":
|
||||
VT[v] = k
|
||||
|
||||
|
@ -79,7 +83,7 @@ WORD_CLSID = "00020900-0000-0000-C000-000000000046"
|
|||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
class _OleStream(StringIO.StringIO):
|
||||
class _OleStream(io.BytesIO):
|
||||
|
||||
"""OLE2 Stream
|
||||
|
||||
|
@ -105,11 +109,11 @@ class _OleStream(StringIO.StringIO):
|
|||
data.append(fp.read(sectorsize))
|
||||
sect = fat[sect]
|
||||
|
||||
data = string.join(data, "")
|
||||
data = b"".join(data)
|
||||
|
||||
# print len(data), size
|
||||
|
||||
StringIO.StringIO.__init__(self, data[:size])
|
||||
io.BytesIO.__init__(self, data[:size])
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -173,7 +177,7 @@ class _OleDirectoryEntry:
|
|||
if right != -1: # 0xFFFFFFFFL:
|
||||
# and then back to the left
|
||||
sid = right
|
||||
while 1:
|
||||
while True:
|
||||
left, right, child = sidlist[sid][4]
|
||||
if left == -1: # 0xFFFFFFFFL:
|
||||
break
|
||||
|
@ -181,7 +185,7 @@ class _OleDirectoryEntry:
|
|||
sid = left
|
||||
else:
|
||||
# couldn't move right; move up instead
|
||||
while 1:
|
||||
while True:
|
||||
ptr = stack[-1]
|
||||
del stack[-1]
|
||||
left, right, child = sidlist[ptr][4]
|
||||
|
@ -208,12 +212,12 @@ class _OleDirectoryEntry:
|
|||
TYPES = ["(invalid)", "(storage)", "(stream)", "(lockbytes)",
|
||||
"(property)", "(root)"]
|
||||
|
||||
print " "*tab + repr(self.name), TYPES[self.type],
|
||||
print(" "*tab + repr(self.name), TYPES[self.type], end=' ')
|
||||
if self.type in (2, 5):
|
||||
print self.size, "bytes",
|
||||
print
|
||||
print(self.size, "bytes", end=' ')
|
||||
print()
|
||||
if self.type in (1, 5) and self.clsid:
|
||||
print " "*tab + "{%s}" % self.clsid
|
||||
print(" "*tab + "{%s}" % self.clsid)
|
||||
|
||||
for kid in self.kids:
|
||||
kid.dump(tab + 2)
|
||||
|
@ -265,7 +269,7 @@ class OleFileIO:
|
|||
def open(self, filename):
|
||||
"""Open an OLE2 file"""
|
||||
|
||||
if type(filename) == type(""):
|
||||
if isinstance(filename, str):
|
||||
self.fp = open(filename, "rb")
|
||||
else:
|
||||
self.fp = filename
|
||||
|
@ -273,7 +277,7 @@ class OleFileIO:
|
|||
header = self.fp.read(512)
|
||||
|
||||
if len(header) != 512 or header[:8] != MAGIC:
|
||||
raise IOError, "not an OLE2 structured storage file"
|
||||
raise IOError("not an OLE2 structured storage file")
|
||||
|
||||
# file clsid (probably never used, so we don't store it)
|
||||
clsid = self._clsid(header[8:24])
|
||||
|
@ -307,7 +311,7 @@ class OleFileIO:
|
|||
if ix == -2 or ix == -1: # ix == 0xFFFFFFFEL or ix == 0xFFFFFFFFL:
|
||||
break
|
||||
s = self.getsect(ix)
|
||||
fat = fat + map(lambda i, s=s: i32(s, i), range(0, len(s), 4))
|
||||
fat = fat + [i32(s, i) for i in range(0, len(s), 4)]
|
||||
self.fat = fat
|
||||
|
||||
def loadminifat(self):
|
||||
|
@ -316,7 +320,7 @@ class OleFileIO:
|
|||
|
||||
s = self._open(self.minifatsect).read()
|
||||
|
||||
self.minifat = map(lambda i, s=s: i32(s, i), range(0, len(s), 4))
|
||||
self.minifat = [i32(s, i) for i in range(0, len(s), 4)]
|
||||
|
||||
def getsect(self, sect):
|
||||
# Read given sector
|
||||
|
@ -327,9 +331,12 @@ class OleFileIO:
|
|||
def _unicode(self, s):
|
||||
# Map unicode string to Latin 1
|
||||
|
||||
# FIXME: some day, Python will provide an official way to handle
|
||||
# Unicode strings, but until then, this will have to do...
|
||||
return filter(ord, s)
|
||||
if bytes is str:
|
||||
# Old version tried to produce a Latin-1 str
|
||||
return s.decode('utf-16').encode('latin-1', 'replace')
|
||||
else:
|
||||
# Provide actual Unicode string
|
||||
return s.decode('utf-16')
|
||||
|
||||
def loaddirectory(self, sect):
|
||||
# Load the directory. The directory is stored in a standard
|
||||
|
@ -340,11 +347,11 @@ class OleFileIO:
|
|||
|
||||
# create list of sid entries
|
||||
self.sidlist = []
|
||||
while 1:
|
||||
while True:
|
||||
entry = fp.read(128)
|
||||
if not entry:
|
||||
break
|
||||
type = ord(entry[66])
|
||||
type = i8(entry[66])
|
||||
name = self._unicode(entry[0:0+i16(entry, 64)])
|
||||
ptrs = i32(entry, 68), i32(entry, 72), i32(entry, 76)
|
||||
sect, size = i32(entry, 116), i32(entry, 120)
|
||||
|
@ -364,7 +371,7 @@ class OleFileIO:
|
|||
return ""
|
||||
return (("%08X-%04X-%04X-%02X%02X-" + "%02X" * 6) %
|
||||
((i32(clsid, 0), i16(clsid, 4), i16(clsid, 6)) +
|
||||
tuple(map(ord, clsid[8:16]))))
|
||||
tuple(map(i8, clsid[8:16]))))
|
||||
|
||||
def _list(self, files, prefix, node):
|
||||
# listdir helper
|
||||
|
@ -385,7 +392,7 @@ class OleFileIO:
|
|||
if kid.name == name:
|
||||
break
|
||||
else:
|
||||
raise IOError, "file not found"
|
||||
raise IOError("file not found")
|
||||
node = kid
|
||||
return node.sid
|
||||
|
||||
|
@ -423,7 +430,7 @@ class OleFileIO:
|
|||
slot = self._find(filename)
|
||||
name, type, sect, size, sids, clsid = self.sidlist[slot]
|
||||
if type != 2:
|
||||
raise IOError, "this file is not a stream"
|
||||
raise IOError("this file is not a stream")
|
||||
return self._open(sect, size)
|
||||
|
||||
##
|
||||
|
@ -480,9 +487,9 @@ class OleFileIO:
|
|||
value = long(i32(s, offset+4)) + (long(i32(s, offset+8))<<32)
|
||||
# FIXME: this is a 64-bit int: "number of 100ns periods
|
||||
# since Jan 1,1601". Should map this to Python time
|
||||
value = value / 10000000L # seconds
|
||||
value = value // 10000000 # seconds
|
||||
elif type == VT_UI1:
|
||||
value = ord(s[offset+4])
|
||||
value = i8(s[offset+4])
|
||||
elif type == VT_CLSID:
|
||||
value = self._clsid(s[offset+4:offset+20])
|
||||
elif type == VT_CF:
|
||||
|
@ -512,17 +519,16 @@ if __name__ == "__main__":
|
|||
for file in sys.argv[1:]:
|
||||
try:
|
||||
ole = OleFileIO(file)
|
||||
print "-" * 68
|
||||
print file
|
||||
print "-" * 68
|
||||
print("-" * 68)
|
||||
print(file)
|
||||
print("-" * 68)
|
||||
ole.dumpdirectory()
|
||||
for file in ole.listdir():
|
||||
if file[-1][0] == "\005":
|
||||
print file
|
||||
print(file)
|
||||
props = ole.getproperties(file)
|
||||
props = props.items()
|
||||
props.sort()
|
||||
props = sorted(props.items())
|
||||
for k, v in props:
|
||||
print " ", k, v
|
||||
except IOError, v:
|
||||
print "***", "cannot read", file, "-", v
|
||||
print(" ", k, v)
|
||||
except IOError as v:
|
||||
print("***", "cannot read", file, "-", v)
|
||||
|
|
|
@ -15,8 +15,9 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import EpsImagePlugin
|
||||
import string
|
||||
from __future__ import print_function
|
||||
|
||||
from . import EpsImagePlugin
|
||||
|
||||
##
|
||||
# Simple Postscript graphics interface.
|
||||
|
@ -52,7 +53,7 @@ class PSDraw:
|
|||
self.fp.flush()
|
||||
|
||||
def setfont(self, font, size):
|
||||
if not self.isofont.has_key(font):
|
||||
if font not in self.isofont:
|
||||
# reencode font
|
||||
self.fp.write("/PSDraw-%s ISOLatin1Encoding /%s E\n" %\
|
||||
(font, font))
|
||||
|
@ -61,7 +62,7 @@ class PSDraw:
|
|||
self.fp.write("/F0 %d /PSDraw-%s F\n" % (size, font))
|
||||
|
||||
def setink(self, ink):
|
||||
print "*** NOT YET IMPLEMENTED ***"
|
||||
print("*** NOT YET IMPLEMENTED ***")
|
||||
|
||||
def line(self, xy0, xy1):
|
||||
xy = xy0 + xy1
|
||||
|
@ -71,8 +72,8 @@ class PSDraw:
|
|||
self.fp.write("%d %d M %d %d 0 Vr\n" % box)
|
||||
|
||||
def text(self, xy, text):
|
||||
text = string.joinfields(string.splitfields(text, "("), "\\(")
|
||||
text = string.joinfields(string.splitfields(text, ")"), "\\)")
|
||||
text = "\\(".join(text.split("("))
|
||||
text = "\\)".join(text.split(")"))
|
||||
xy = xy + (text,)
|
||||
self.fp.write("%d %d M (%s) S\n" % xy)
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import string
|
||||
from ._binary import o8
|
||||
|
||||
##
|
||||
# File handler for Teragon-style palette files.
|
||||
|
@ -24,20 +24,20 @@ class PaletteFile:
|
|||
|
||||
def __init__(self, fp):
|
||||
|
||||
self.palette = map(lambda i: (i, i, i), range(256))
|
||||
self.palette = [(i, i, i) for i in range(256)]
|
||||
|
||||
while 1:
|
||||
while True:
|
||||
|
||||
s = fp.readline()
|
||||
|
||||
if not s:
|
||||
break
|
||||
if s[0] == "#":
|
||||
if s[0:1] == b"#":
|
||||
continue
|
||||
if len(s) > 100:
|
||||
raise SyntaxError, "bad palette file"
|
||||
raise SyntaxError("bad palette file")
|
||||
|
||||
v = map(int, string.split(s))
|
||||
v = [int(x) for x in s.split()]
|
||||
try:
|
||||
[i, r, g, b] = v
|
||||
except ValueError:
|
||||
|
@ -45,9 +45,9 @@ class PaletteFile:
|
|||
g = b = r
|
||||
|
||||
if 0 <= i <= 255:
|
||||
self.palette[i] = chr(r) + chr(g) + chr(b)
|
||||
self.palette[i] = o8(r) + o8(g) + o8(b)
|
||||
|
||||
self.palette = string.join(self.palette, "")
|
||||
self.palette = b"".join(self.palette)
|
||||
|
||||
|
||||
def getpalette(self):
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
__version__ = "1.0"
|
||||
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
_Palm8BitColormapValues = (
|
||||
( 255, 255, 255 ), ( 255, 204, 255 ), ( 255, 153, 255 ), ( 255, 102, 255 ),
|
||||
|
@ -80,7 +80,7 @@ _Palm8BitColormapValues = (
|
|||
# so build a prototype image to be used for palette resampling
|
||||
def build_prototype_image():
|
||||
image = Image.new("L", (1,len(_Palm8BitColormapValues),))
|
||||
image.putdata(range(len(_Palm8BitColormapValues)))
|
||||
image.putdata(list(range(len(_Palm8BitColormapValues))))
|
||||
palettedata = ()
|
||||
for i in range(len(_Palm8BitColormapValues)):
|
||||
palettedata = palettedata + _Palm8BitColormapValues[i]
|
||||
|
@ -107,8 +107,8 @@ _COMPRESSION_TYPES = {
|
|||
"scanline": 0x00,
|
||||
}
|
||||
|
||||
def o16b(i):
|
||||
return chr(i>>8&255) + chr(i&255)
|
||||
o8 = _binary.o8
|
||||
o16b = _binary.o16be
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -127,7 +127,7 @@ def _save(im, fp, filename, check=0):
|
|||
bpp = 8
|
||||
version = 1
|
||||
|
||||
elif im.mode == "L" and im.encoderinfo.has_key("bpp") and im.encoderinfo["bpp"] in (1, 2, 4):
|
||||
elif im.mode == "L" and "bpp" in im.encoderinfo and im.encoderinfo["bpp"] in (1, 2, 4):
|
||||
|
||||
# this is 8-bit grayscale, so we shift it to get the high-order bits, and invert it because
|
||||
# Palm does greyscale from white (0) to black (1)
|
||||
|
@ -138,7 +138,7 @@ def _save(im, fp, filename, check=0):
|
|||
rawmode = "P;" + str(bpp)
|
||||
version = 1
|
||||
|
||||
elif im.mode == "L" and im.info.has_key("bpp") and im.info["bpp"] in (1, 2, 4):
|
||||
elif im.mode == "L" and "bpp" in im.info and im.info["bpp"] in (1, 2, 4):
|
||||
|
||||
# here we assume that even though the inherent mode is 8-bit grayscale, only
|
||||
# the lower bpp bits are significant. We invert them to match the Palm.
|
||||
|
@ -158,7 +158,7 @@ def _save(im, fp, filename, check=0):
|
|||
|
||||
else:
|
||||
|
||||
raise IOError, "cannot write mode %s as Palm" % im.mode
|
||||
raise IOError("cannot write mode %s as Palm" % im.mode)
|
||||
|
||||
if check:
|
||||
return check
|
||||
|
@ -172,12 +172,12 @@ def _save(im, fp, filename, check=0):
|
|||
cols = im.size[0]
|
||||
rows = im.size[1]
|
||||
|
||||
rowbytes = ((cols + (16/bpp - 1)) / (16 / bpp)) * 2;
|
||||
rowbytes = ((cols + (16//bpp - 1)) / (16 // bpp)) * 2;
|
||||
transparent_index = 0
|
||||
compression_type = _COMPRESSION_TYPES["none"]
|
||||
|
||||
flags = 0;
|
||||
if im.mode == "P" and im.info.has_key("custom-colormap"):
|
||||
if im.mode == "P" and "custom-colormap" in im.info:
|
||||
flags = flags & _FLAGS["custom-colormap"]
|
||||
colormapsize = 4 * 256 + 2;
|
||||
colormapmode = im.palette.mode
|
||||
|
@ -185,17 +185,17 @@ def _save(im, fp, filename, check=0):
|
|||
else:
|
||||
colormapsize = 0
|
||||
|
||||
if im.info.has_key("offset"):
|
||||
offset = (rowbytes * rows + 16 + 3 + colormapsize) / 4;
|
||||
if "offset" in im.info:
|
||||
offset = (rowbytes * rows + 16 + 3 + colormapsize) // 4;
|
||||
else:
|
||||
offset = 0
|
||||
|
||||
fp.write(o16b(cols) + o16b(rows) + o16b(rowbytes) + o16b(flags))
|
||||
fp.write(chr(bpp))
|
||||
fp.write(chr(version))
|
||||
fp.write(o8(bpp))
|
||||
fp.write(o8(version))
|
||||
fp.write(o16b(offset))
|
||||
fp.write(chr(transparent_index))
|
||||
fp.write(chr(compression_type))
|
||||
fp.write(o8(transparent_index))
|
||||
fp.write(o8(compression_type))
|
||||
fp.write(o16b(0)) # reserved by Palm
|
||||
|
||||
# now write colormap if necessary
|
||||
|
@ -203,11 +203,11 @@ def _save(im, fp, filename, check=0):
|
|||
if colormapsize > 0:
|
||||
fp.write(o16b(256))
|
||||
for i in range(256):
|
||||
fp.write(chr(i))
|
||||
fp.write(o8(i))
|
||||
if colormapmode == 'RGB':
|
||||
fp.write(chr(colormap[3 * i]) + chr(colormap[3 * i + 1]) + chr(colormap[3 * i + 2]))
|
||||
fp.write(o8(colormap[3 * i]) + o8(colormap[3 * i + 1]) + o8(colormap[3 * i + 2]))
|
||||
elif colormapmode == 'RGBA':
|
||||
fp.write(chr(colormap[4 * i]) + chr(colormap[4 * i + 1]) + chr(colormap[4 * i + 2]))
|
||||
fp.write(o8(colormap[4 * i]) + o8(colormap[4 * i + 1]) + o8(colormap[4 * i + 2]))
|
||||
|
||||
# now convert data to raw form
|
||||
ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, rowbytes, 1))])
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
__version__ = "0.1"
|
||||
|
||||
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
i8 = _binary.i8
|
||||
|
||||
##
|
||||
# Image plugin for PhotoCD images. This plugin only reads the 768x512
|
||||
|
@ -36,10 +38,10 @@ class PcdImageFile(ImageFile.ImageFile):
|
|||
self.fp.seek(2048)
|
||||
s = self.fp.read(2048)
|
||||
|
||||
if s[:4] != "PCD_":
|
||||
raise SyntaxError, "not a PCD file"
|
||||
if s[:4] != b"PCD_":
|
||||
raise SyntaxError("not a PCD file")
|
||||
|
||||
orientation = ord(s[1538]) & 3
|
||||
orientation = i8(s[1538]) & 3
|
||||
if orientation == 1:
|
||||
self.tile_post_rotate = 90 # hack
|
||||
elif orientation == 3:
|
||||
|
|
|
@ -16,10 +16,9 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import Image
|
||||
import FontFile
|
||||
|
||||
import string
|
||||
from . import Image
|
||||
from . import FontFile
|
||||
from . import _binary
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# declarations
|
||||
|
@ -43,19 +42,14 @@ BYTES_PER_ROW = [
|
|||
lambda bits: ((bits+63) >> 3) & ~7,
|
||||
]
|
||||
|
||||
|
||||
def l16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
def l32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
|
||||
def b16(c):
|
||||
return ord(c[1]) + (ord(c[0])<<8)
|
||||
def b32(c):
|
||||
return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
|
||||
i8 = _binary.i8
|
||||
l16 = _binary.i16le
|
||||
l32 = _binary.i32le
|
||||
b16 = _binary.i16be
|
||||
b32 = _binary.i32be
|
||||
|
||||
def sz(s, o):
|
||||
return s[o:string.index(s, "\0", o)]
|
||||
return s[o:s.index(b"\0", o)]
|
||||
|
||||
##
|
||||
# Font file plugin for the X11 PCF format.
|
||||
|
@ -68,7 +62,7 @@ class PcfFontFile(FontFile.FontFile):
|
|||
|
||||
magic = l32(fp.read(4))
|
||||
if magic != PCF_MAGIC:
|
||||
raise SyntaxError, "not a PCF file"
|
||||
raise SyntaxError("not a PCF file")
|
||||
|
||||
FontFile.FontFile.__init__(self)
|
||||
|
||||
|
@ -126,7 +120,7 @@ class PcfFontFile(FontFile.FontFile):
|
|||
# read property description
|
||||
p = []
|
||||
for i in range(nprops):
|
||||
p.append((i32(fp.read(4)), ord(fp.read(1)), i32(fp.read(4))))
|
||||
p.append((i32(fp.read(4)), i8(fp.read(1)), i32(fp.read(4))))
|
||||
if nprops & 3:
|
||||
fp.seek(4 - (nprops & 3), 1) # pad
|
||||
|
||||
|
@ -155,11 +149,11 @@ class PcfFontFile(FontFile.FontFile):
|
|||
|
||||
# "compressed" metrics
|
||||
for i in range(i16(fp.read(2))):
|
||||
left = ord(fp.read(1)) - 128
|
||||
right = ord(fp.read(1)) - 128
|
||||
width = ord(fp.read(1)) - 128
|
||||
ascent = ord(fp.read(1)) - 128
|
||||
descent = ord(fp.read(1)) - 128
|
||||
left = i8(fp.read(1)) - 128
|
||||
right = i8(fp.read(1)) - 128
|
||||
width = i8(fp.read(1)) - 128
|
||||
ascent = i8(fp.read(1)) - 128
|
||||
descent = i8(fp.read(1)) - 128
|
||||
xsize = right - left
|
||||
ysize = ascent + descent
|
||||
append(
|
||||
|
@ -198,7 +192,7 @@ class PcfFontFile(FontFile.FontFile):
|
|||
nbitmaps = i32(fp.read(4))
|
||||
|
||||
if nbitmaps != len(metrics):
|
||||
raise IOError, "Wrong number of bitmaps"
|
||||
raise IOError("Wrong number of bitmaps")
|
||||
|
||||
offsets = []
|
||||
for i in range(nbitmaps):
|
||||
|
@ -226,7 +220,7 @@ class PcfFontFile(FontFile.FontFile):
|
|||
x, y, l, r, w, a, d, f = metrics[i]
|
||||
b, e = offsets[i], offsets[i+1]
|
||||
bitmaps.append(
|
||||
Image.fromstring("1", (x, y), data[b:e], "raw", mode, pad(x))
|
||||
Image.frombytes("1", (x, y), data[b:e], "raw", mode, pad(x))
|
||||
)
|
||||
|
||||
return bitmaps
|
||||
|
|
|
@ -27,13 +27,14 @@
|
|||
|
||||
__version__ = "0.6"
|
||||
|
||||
import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
def i16(c,o):
|
||||
return ord(c[o]) + (ord(c[o+1])<<8)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16le
|
||||
o8 = _binary.o8
|
||||
|
||||
def _accept(prefix):
|
||||
return ord(prefix[0]) == 10 and ord(prefix[1]) in [0, 2, 3, 5]
|
||||
return i8(prefix[0]) == 10 and i8(prefix[1]) in [0, 2, 3, 5]
|
||||
|
||||
##
|
||||
# Image plugin for Paintbrush images.
|
||||
|
@ -48,17 +49,17 @@ class PcxImageFile(ImageFile.ImageFile):
|
|||
# header
|
||||
s = self.fp.read(128)
|
||||
if not _accept(s):
|
||||
raise SyntaxError, "not a PCX file"
|
||||
raise SyntaxError("not a PCX file")
|
||||
|
||||
# image
|
||||
bbox = i16(s,4), i16(s,6), i16(s,8)+1, i16(s,10)+1
|
||||
if bbox[2] <= bbox[0] or bbox[3] <= bbox[1]:
|
||||
raise SyntaxError, "bad PCX image size"
|
||||
raise SyntaxError("bad PCX image size")
|
||||
|
||||
# format
|
||||
version = ord(s[1])
|
||||
bits = ord(s[3])
|
||||
planes = ord(s[65])
|
||||
version = i8(s[1])
|
||||
bits = i8(s[3])
|
||||
planes = i8(s[65])
|
||||
stride = i16(s,66)
|
||||
|
||||
self.info["dpi"] = i16(s,12), i16(s,14)
|
||||
|
@ -76,10 +77,10 @@ class PcxImageFile(ImageFile.ImageFile):
|
|||
# FIXME: hey, this doesn't work with the incremental loader !!!
|
||||
self.fp.seek(-769, 2)
|
||||
s = self.fp.read(769)
|
||||
if len(s) == 769 and ord(s[0]) == 12:
|
||||
if len(s) == 769 and i8(s[0]) == 12:
|
||||
# check if the palette is linear greyscale
|
||||
for i in range(256):
|
||||
if s[i*3+1:i*3+4] != chr(i)*3:
|
||||
if s[i*3+1:i*3+4] != o8(i)*3:
|
||||
mode = rawmode = "P"
|
||||
break
|
||||
if mode == "P":
|
||||
|
@ -91,7 +92,7 @@ class PcxImageFile(ImageFile.ImageFile):
|
|||
rawmode = "RGB;L"
|
||||
|
||||
else:
|
||||
raise IOError, "unknown PCX mode"
|
||||
raise IOError("unknown PCX mode")
|
||||
|
||||
self.mode = mode
|
||||
self.size = bbox[2]-bbox[0], bbox[3]-bbox[1]
|
||||
|
@ -111,21 +112,20 @@ SAVE = {
|
|||
"RGB": (5, 8, 3, "RGB;L"),
|
||||
}
|
||||
|
||||
def o16(i):
|
||||
return chr(i&255) + chr(i>>8&255)
|
||||
o16 = _binary.o16le
|
||||
|
||||
def _save(im, fp, filename, check=0):
|
||||
|
||||
try:
|
||||
version, bits, planes, rawmode = SAVE[im.mode]
|
||||
except KeyError:
|
||||
raise ValueError, "Cannot save %s images as PCX" % im.mode
|
||||
raise ValueError("Cannot save %s images as PCX" % im.mode)
|
||||
|
||||
if check:
|
||||
return check
|
||||
|
||||
# bytes per plane
|
||||
stride = (im.size[0] * bits + 7) / 8
|
||||
stride = (im.size[0] * bits + 7) // 8
|
||||
|
||||
# under windows, we could determine the current screen size with
|
||||
# "Image.core.display_mode()[1]", but I think that's overkill...
|
||||
|
@ -136,11 +136,11 @@ def _save(im, fp, filename, check=0):
|
|||
|
||||
# PCX header
|
||||
fp.write(
|
||||
chr(10) + chr(version) + chr(1) + chr(bits) + o16(0) +
|
||||
o8(10) + o8(version) + o8(1) + o8(bits) + o16(0) +
|
||||
o16(0) + o16(im.size[0]-1) + o16(im.size[1]-1) + o16(dpi[0]) +
|
||||
o16(dpi[1]) + chr(0)*24 + chr(255)*24 + chr(0) + chr(planes) +
|
||||
o16(dpi[1]) + b"\0"*24 + b"\xFF"*24 + b"\0" + o8(planes) +
|
||||
o16(stride) + o16(1) + o16(screen[0]) + o16(screen[1]) +
|
||||
chr(0)*54
|
||||
b"\0"*54
|
||||
)
|
||||
|
||||
assert fp.tell() == 128
|
||||
|
@ -150,13 +150,13 @@ def _save(im, fp, filename, check=0):
|
|||
|
||||
if im.mode == "P":
|
||||
# colour palette
|
||||
fp.write(chr(12))
|
||||
fp.write(o8(12))
|
||||
fp.write(im.im.getpalette("RGB", "RGB")) # 768 bytes
|
||||
elif im.mode == "L":
|
||||
# greyscale palette
|
||||
fp.write(chr(12))
|
||||
fp.write(o8(12))
|
||||
for i in range(256):
|
||||
fp.write(chr(i)*3)
|
||||
fp.write(o8(i)*3)
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# registry
|
||||
|
|
|
@ -22,8 +22,9 @@
|
|||
|
||||
__version__ = "0.4"
|
||||
|
||||
import Image, ImageFile
|
||||
import StringIO
|
||||
from . import Image, ImageFile
|
||||
from ._binary import i8
|
||||
import io
|
||||
|
||||
|
||||
#
|
||||
|
@ -60,6 +61,16 @@ def _save(im, fp, filename):
|
|||
|
||||
xref = [0]*(5+1) # placeholders
|
||||
|
||||
class TextWriter:
|
||||
def __init__(self, fp):
|
||||
self.fp = fp
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.fp, name)
|
||||
def write(self, value):
|
||||
self.fp.write(value.encode('latin-1'))
|
||||
|
||||
fp = TextWriter(fp)
|
||||
|
||||
fp.write("%PDF-1.2\n")
|
||||
fp.write("% created by PIL PDF driver " + __version__ + "\n")
|
||||
|
||||
|
@ -90,11 +101,11 @@ def _save(im, fp, filename):
|
|||
colorspace = "[ /Indexed /DeviceRGB 255 <"
|
||||
palette = im.im.getpalette("RGB")
|
||||
for i in range(256):
|
||||
r = ord(palette[i*3])
|
||||
g = ord(palette[i*3+1])
|
||||
b = ord(palette[i*3+2])
|
||||
r = i8(palette[i*3])
|
||||
g = i8(palette[i*3+1])
|
||||
b = i8(palette[i*3+2])
|
||||
colorspace = colorspace + "%02x%02x%02x " % (r, g, b)
|
||||
colorspace = colorspace + "> ]"
|
||||
colorspace = colorspace + b"> ]"
|
||||
procset = "/ImageI" # indexed color
|
||||
elif im.mode == "RGB":
|
||||
filter = "/DCTDecode"
|
||||
|
@ -127,7 +138,7 @@ def _save(im, fp, filename):
|
|||
#
|
||||
# image
|
||||
|
||||
op = StringIO.StringIO()
|
||||
op = io.BytesIO()
|
||||
|
||||
if filter == "/ASCIIHexDecode":
|
||||
if bits == 1:
|
||||
|
@ -158,7 +169,7 @@ def _save(im, fp, filename):
|
|||
ColorSpace = colorspace)
|
||||
|
||||
fp.write("stream\n")
|
||||
fp.write(op.getvalue())
|
||||
fp.fp.write(op.getvalue())
|
||||
fp.write("\nendstream\n")
|
||||
|
||||
_endobj(fp)
|
||||
|
@ -178,15 +189,15 @@ def _save(im, fp, filename):
|
|||
#
|
||||
# page contents
|
||||
|
||||
op = StringIO.StringIO()
|
||||
op = TextWriter(io.BytesIO())
|
||||
|
||||
op.write("q %d 0 0 %d 0 0 cm /image Do Q\n" % (int(width * 72.0 / resolution), int(height * 72.0 / resolution)))
|
||||
|
||||
xref[5] = fp.tell()
|
||||
_obj(fp, 5, Length = len(op.getvalue()))
|
||||
_obj(fp, 5, Length = len(op.fp.getvalue()))
|
||||
|
||||
fp.write("stream\n")
|
||||
fp.write(op.getvalue())
|
||||
fp.fp.write(op.fp.getvalue())
|
||||
fp.write("\nendstream\n")
|
||||
|
||||
_endobj(fp)
|
||||
|
|
|
@ -21,16 +21,13 @@
|
|||
|
||||
__version__ = "0.1"
|
||||
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
#
|
||||
# helpers
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
i16 = _binary.i16le
|
||||
i32 = _binary.i32le
|
||||
|
||||
##
|
||||
# Image plugin for PIXAR raster images.
|
||||
|
@ -44,8 +41,8 @@ class PixarImageFile(ImageFile.ImageFile):
|
|||
|
||||
# assuming a 4-byte magic label (FIXME: add "_accept" hook)
|
||||
s = self.fp.read(4)
|
||||
if s != "\200\350\000\000":
|
||||
raise SyntaxError, "not a PIXAR file"
|
||||
if s != b"\200\350\000\000":
|
||||
raise SyntaxError("not a PIXAR file")
|
||||
|
||||
# read rest of header
|
||||
s = s + self.fp.read(508)
|
||||
|
|
|
@ -31,22 +31,23 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
__version__ = "0.9"
|
||||
|
||||
import re, string
|
||||
import re
|
||||
|
||||
import Image, ImageFile, ImagePalette, zlib
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
import zlib
|
||||
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16be
|
||||
i32 = _binary.i32be
|
||||
|
||||
is_cid = re.compile(b"\w\w\w\w").match
|
||||
|
||||
|
||||
def i16(c):
|
||||
return ord(c[1]) + (ord(c[0])<<8)
|
||||
def i32(c):
|
||||
return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
|
||||
|
||||
is_cid = re.compile("\w\w\w\w").match
|
||||
|
||||
|
||||
_MAGIC = "\211PNG\r\n\032\n"
|
||||
_MAGIC = b"\211PNG\r\n\032\n"
|
||||
|
||||
|
||||
_MODES = {
|
||||
|
@ -96,7 +97,7 @@ class ChunkStream:
|
|||
len = i32(s)
|
||||
|
||||
if not is_cid(cid):
|
||||
raise SyntaxError, "broken PNG file (chunk %s)" % repr(cid)
|
||||
raise SyntaxError("broken PNG file (chunk %s)" % repr(cid))
|
||||
|
||||
return cid, pos, len
|
||||
|
||||
|
@ -111,8 +112,8 @@ class ChunkStream:
|
|||
"Call the appropriate chunk handler"
|
||||
|
||||
if Image.DEBUG:
|
||||
print "STREAM", cid, pos, len
|
||||
return getattr(self, "chunk_" + cid)(pos, len)
|
||||
print("STREAM", cid, pos, len)
|
||||
return getattr(self, "chunk_" + cid.decode('ascii'))(pos, len)
|
||||
|
||||
def crc(self, cid, data):
|
||||
"Read and verify checksum"
|
||||
|
@ -120,22 +121,22 @@ class ChunkStream:
|
|||
crc1 = Image.core.crc32(data, Image.core.crc32(cid))
|
||||
crc2 = i16(self.fp.read(2)), i16(self.fp.read(2))
|
||||
if crc1 != crc2:
|
||||
raise SyntaxError, "broken PNG file"\
|
||||
"(bad header checksum in %s)" % cid
|
||||
raise SyntaxError("broken PNG file"\
|
||||
"(bad header checksum in %s)" % cid)
|
||||
|
||||
def crc_skip(self, cid, data):
|
||||
"Read checksum. Used if the C module is not present"
|
||||
|
||||
self.fp.read(4)
|
||||
|
||||
def verify(self, endchunk = "IEND"):
|
||||
def verify(self, endchunk = b"IEND"):
|
||||
|
||||
# Simple approach; just calculate checksum for all remaining
|
||||
# blocks. Must be called directly after open.
|
||||
|
||||
cids = []
|
||||
|
||||
while 1:
|
||||
while True:
|
||||
cid, pos, len = self.read()
|
||||
if cid == endchunk:
|
||||
break
|
||||
|
@ -157,11 +158,18 @@ class PngInfo:
|
|||
self.chunks.append((cid, data))
|
||||
|
||||
def add_text(self, key, value, zip=0):
|
||||
# The tEXt chunk stores latin-1 text
|
||||
if not isinstance(key, bytes):
|
||||
key = key.encode('latin-1', 'strict')
|
||||
|
||||
if not isinstance(value, bytes):
|
||||
value = value.encode('latin-1', 'replace')
|
||||
|
||||
if zip:
|
||||
import zlib
|
||||
self.add("zTXt", key + "\0\0" + zlib.compress(value))
|
||||
self.add(b"zTXt", key + b"\0\0" + zlib.compress(value))
|
||||
else:
|
||||
self.add("tEXt", key + "\0" + value)
|
||||
self.add(b"tEXt", key + b"\0" + value)
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# PNG image stream (IHDR/IEND)
|
||||
|
@ -189,11 +197,11 @@ class PngStream(ChunkStream):
|
|||
# Null separator 1 byte (null character)
|
||||
# Compression method 1 byte (0)
|
||||
# Compressed profile n bytes (zlib with deflate compression)
|
||||
i = string.find(s, chr(0))
|
||||
i = s.find(b"\0")
|
||||
if Image.DEBUG:
|
||||
print "iCCP profile name", s[:i]
|
||||
print "Compression method", ord(s[i])
|
||||
comp_method = ord(s[i])
|
||||
print("iCCP profile name", s[:i])
|
||||
print("Compression method", i8(s[i]))
|
||||
comp_method = i8(s[i])
|
||||
if comp_method != 0:
|
||||
raise SyntaxError("Unknown compression method %s in iCCP chunk" % comp_method)
|
||||
try:
|
||||
|
@ -209,13 +217,13 @@ class PngStream(ChunkStream):
|
|||
s = ImageFile._safe_read(self.fp, len)
|
||||
self.im_size = i32(s), i32(s[4:])
|
||||
try:
|
||||
self.im_mode, self.im_rawmode = _MODES[(ord(s[8]), ord(s[9]))]
|
||||
self.im_mode, self.im_rawmode = _MODES[(i8(s[8]), i8(s[9]))]
|
||||
except:
|
||||
pass
|
||||
if ord(s[12]):
|
||||
if i8(s[12]):
|
||||
self.im_info["interlace"] = 1
|
||||
if ord(s[11]):
|
||||
raise SyntaxError, "unknown filter category"
|
||||
if i8(s[11]):
|
||||
raise SyntaxError("unknown filter category")
|
||||
return s
|
||||
|
||||
def chunk_IDAT(self, pos, len):
|
||||
|
@ -243,7 +251,7 @@ class PngStream(ChunkStream):
|
|||
# transparency
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
if self.im_mode == "P":
|
||||
i = string.find(s, chr(0))
|
||||
i = s.find(b"\0")
|
||||
if i >= 0:
|
||||
self.im_info["transparency"] = i
|
||||
elif self.im_mode == "L":
|
||||
|
@ -264,7 +272,7 @@ class PngStream(ChunkStream):
|
|||
# pixels per unit
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
px, py = i32(s), i32(s[4:])
|
||||
unit = ord(s[8])
|
||||
unit = i8(s[8])
|
||||
if unit == 1: # meter
|
||||
dpi = int(px * 0.0254 + 0.5), int(py * 0.0254 + 0.5)
|
||||
self.im_info["dpi"] = dpi
|
||||
|
@ -277,10 +285,14 @@ class PngStream(ChunkStream):
|
|||
# text
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
try:
|
||||
k, v = string.split(s, "\0", 1)
|
||||
k, v = s.split(b"\0", 1)
|
||||
except ValueError:
|
||||
k = s; v = "" # fallback for broken tEXt tags
|
||||
k = s; v = b"" # fallback for broken tEXt tags
|
||||
if k:
|
||||
if bytes is not str:
|
||||
k = k.decode('latin-1', 'strict')
|
||||
v = v.decode('latin-1', 'replace')
|
||||
|
||||
self.im_info[k] = self.im_text[k] = v
|
||||
return s
|
||||
|
||||
|
@ -288,12 +300,18 @@ class PngStream(ChunkStream):
|
|||
|
||||
# compressed text
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
k, v = string.split(s, "\0", 1)
|
||||
comp_method = ord(v[0])
|
||||
k, v = s.split(b"\0", 1)
|
||||
comp_method = i8(v[0])
|
||||
if comp_method != 0:
|
||||
raise SyntaxError("Unknown compression method %s in zTXt chunk" % comp_method)
|
||||
import zlib
|
||||
self.im_info[k] = self.im_text[k] = zlib.decompress(v[1:])
|
||||
v = zlib.decompress(v[1:])
|
||||
|
||||
if bytes is not str:
|
||||
k = k.decode('latin-1', 'strict')
|
||||
v = v.decode('latin-1', 'replace')
|
||||
|
||||
self.im_info[k] = self.im_text[k] = v
|
||||
return s
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -313,14 +331,14 @@ class PngImageFile(ImageFile.ImageFile):
|
|||
def _open(self):
|
||||
|
||||
if self.fp.read(8) != _MAGIC:
|
||||
raise SyntaxError, "not a PNG file"
|
||||
raise SyntaxError("not a PNG file")
|
||||
|
||||
#
|
||||
# Parse headers up to the first IDAT chunk
|
||||
|
||||
self.png = PngStream(self.fp)
|
||||
|
||||
while 1:
|
||||
while True:
|
||||
|
||||
#
|
||||
# get next chunk
|
||||
|
@ -333,7 +351,7 @@ class PngImageFile(ImageFile.ImageFile):
|
|||
break
|
||||
except AttributeError:
|
||||
if Image.DEBUG:
|
||||
print cid, pos, len, "(unknown)"
|
||||
print(cid, pos, len, "(unknown)")
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
|
||||
self.png.crc(cid, s)
|
||||
|
@ -390,9 +408,9 @@ class PngImageFile(ImageFile.ImageFile):
|
|||
|
||||
cid, pos, len = self.png.read()
|
||||
|
||||
if cid not in ["IDAT", "DDAT"]:
|
||||
if cid not in [b"IDAT", b"DDAT"]:
|
||||
self.png.push(cid, pos, len)
|
||||
return ""
|
||||
return b""
|
||||
|
||||
self.__idat = len # empty chunks are allowed
|
||||
|
||||
|
@ -417,33 +435,31 @@ class PngImageFile(ImageFile.ImageFile):
|
|||
# --------------------------------------------------------------------
|
||||
# PNG writer
|
||||
|
||||
def o16(i):
|
||||
return chr(i>>8&255) + chr(i&255)
|
||||
|
||||
def o32(i):
|
||||
return chr(i>>24&255) + chr(i>>16&255) + chr(i>>8&255) + chr(i&255)
|
||||
o8 = _binary.o8
|
||||
o16 = _binary.o16be
|
||||
o32 = _binary.o32be
|
||||
|
||||
_OUTMODES = {
|
||||
# supported PIL modes, and corresponding rawmodes/bits/color combinations
|
||||
"1": ("1", chr(1)+chr(0)),
|
||||
"L;1": ("L;1", chr(1)+chr(0)),
|
||||
"L;2": ("L;2", chr(2)+chr(0)),
|
||||
"L;4": ("L;4", chr(4)+chr(0)),
|
||||
"L": ("L", chr(8)+chr(0)),
|
||||
"LA": ("LA", chr(8)+chr(4)),
|
||||
"I": ("I;16B", chr(16)+chr(0)),
|
||||
"P;1": ("P;1", chr(1)+chr(3)),
|
||||
"P;2": ("P;2", chr(2)+chr(3)),
|
||||
"P;4": ("P;4", chr(4)+chr(3)),
|
||||
"P": ("P", chr(8)+chr(3)),
|
||||
"RGB": ("RGB", chr(8)+chr(2)),
|
||||
"RGBA":("RGBA", chr(8)+chr(6)),
|
||||
"1": ("1", b'\x01\x00'),
|
||||
"L;1": ("L;1", b'\x01\x00'),
|
||||
"L;2": ("L;2", b'\x02\x00'),
|
||||
"L;4": ("L;4", b'\x04\x00'),
|
||||
"L": ("L", b'\x08\x00'),
|
||||
"LA": ("LA", b'\x08\x04'),
|
||||
"I": ("I;16B", b'\x10\x00'),
|
||||
"P;1": ("P;1", b'\x01\x03'),
|
||||
"P;2": ("P;2", b'\x02\x03'),
|
||||
"P;4": ("P;4", b'\x04\x03'),
|
||||
"P": ("P", b'\x08\x03'),
|
||||
"RGB": ("RGB", b'\x08\x02'),
|
||||
"RGBA":("RGBA", b'\x08\x06'),
|
||||
}
|
||||
|
||||
def putchunk(fp, cid, *data):
|
||||
"Write a PNG chunk (including CRC field)"
|
||||
|
||||
data = string.join(data, "")
|
||||
data = b"".join(data)
|
||||
|
||||
fp.write(o32(len(data)) + cid)
|
||||
fp.write(data)
|
||||
|
@ -457,7 +473,7 @@ class _idat:
|
|||
self.fp = fp
|
||||
self.chunk = chunk
|
||||
def write(self, data):
|
||||
self.chunk(self.fp, "IDAT", data)
|
||||
self.chunk(self.fp, b"IDAT", data)
|
||||
|
||||
def _save(im, fp, filename, chunk=putchunk, check=0):
|
||||
# save an image to disk (called by the save method)
|
||||
|
@ -469,7 +485,7 @@ def _save(im, fp, filename, chunk=putchunk, check=0):
|
|||
#
|
||||
# attempt to minimize storage requirements for palette images
|
||||
|
||||
if im.encoderinfo.has_key("bits"):
|
||||
if "bits" in im.encoderinfo:
|
||||
|
||||
# number of bits specified by user
|
||||
n = 1 << im.encoderinfo["bits"]
|
||||
|
@ -492,18 +508,18 @@ def _save(im, fp, filename, chunk=putchunk, check=0):
|
|||
mode = "%s;%d" % (mode, bits)
|
||||
|
||||
# encoder options
|
||||
if im.encoderinfo.has_key("dictionary"):
|
||||
if "dictionary" in im.encoderinfo:
|
||||
dictionary = im.encoderinfo["dictionary"]
|
||||
else:
|
||||
dictionary = ""
|
||||
dictionary = b""
|
||||
|
||||
im.encoderconfig = (im.encoderinfo.has_key("optimize"), dictionary)
|
||||
im.encoderconfig = ("optimize" in im.encoderinfo, dictionary)
|
||||
|
||||
# get the corresponding PNG mode
|
||||
try:
|
||||
rawmode, mode = _OUTMODES[mode]
|
||||
except KeyError:
|
||||
raise IOError, "cannot write mode %s as PNG" % mode
|
||||
raise IOError("cannot write mode %s as PNG" % mode)
|
||||
|
||||
if check:
|
||||
return check
|
||||
|
@ -513,39 +529,39 @@ def _save(im, fp, filename, chunk=putchunk, check=0):
|
|||
|
||||
fp.write(_MAGIC)
|
||||
|
||||
chunk(fp, "IHDR",
|
||||
chunk(fp, b"IHDR",
|
||||
o32(im.size[0]), o32(im.size[1]), # 0: size
|
||||
mode, # 8: depth/type
|
||||
chr(0), # 10: compression
|
||||
chr(0), # 11: filter category
|
||||
chr(0)) # 12: interlace flag
|
||||
b'\0', # 10: compression
|
||||
b'\0', # 11: filter category
|
||||
b'\0') # 12: interlace flag
|
||||
|
||||
if im.mode == "P":
|
||||
chunk(fp, "PLTE", im.im.getpalette("RGB"))
|
||||
chunk(fp, b"PLTE", im.im.getpalette("RGB"))
|
||||
|
||||
if im.encoderinfo.has_key("transparency"):
|
||||
if "transparency" in im.encoderinfo:
|
||||
if im.mode == "P":
|
||||
transparency = max(0, min(255, im.encoderinfo["transparency"]))
|
||||
chunk(fp, "tRNS", chr(255) * transparency + chr(0))
|
||||
chunk(fp, b"tRNS", b'\xFF' * transparency + b'\0')
|
||||
elif im.mode == "L":
|
||||
transparency = max(0, min(65535, im.encoderinfo["transparency"]))
|
||||
chunk(fp, "tRNS", o16(transparency))
|
||||
chunk(fp, b"tRNS", o16(transparency))
|
||||
elif im.mode == "RGB":
|
||||
red, green, blue = im.encoderinfo["transparency"]
|
||||
chunk(fp, "tRNS", o16(red) + o16(green) + o16(blue))
|
||||
chunk(fp, b"tRNS", o16(red) + o16(green) + o16(blue))
|
||||
else:
|
||||
raise IOError("cannot use transparency for this mode")
|
||||
|
||||
if 0:
|
||||
# FIXME: to be supported some day
|
||||
chunk(fp, "gAMA", o32(int(gamma * 100000.0)))
|
||||
chunk(fp, b"gAMA", o32(int(gamma * 100000.0)))
|
||||
|
||||
dpi = im.encoderinfo.get("dpi")
|
||||
if dpi:
|
||||
chunk(fp, "pHYs",
|
||||
chunk(fp, b"pHYs",
|
||||
o32(int(dpi[0] / 0.0254 + 0.5)),
|
||||
o32(int(dpi[1] / 0.0254 + 0.5)),
|
||||
chr(1))
|
||||
b'\x01')
|
||||
|
||||
info = im.encoderinfo.get("pnginfo")
|
||||
if info:
|
||||
|
@ -553,7 +569,7 @@ def _save(im, fp, filename, chunk=putchunk, check=0):
|
|||
chunk(fp, cid, data)
|
||||
|
||||
# ICC profile writing support -- 2008-06-06 Florian Hoech
|
||||
if im.info.has_key("icc_profile"):
|
||||
if "icc_profile" in im.info:
|
||||
# ICC profile
|
||||
# according to PNG spec, the iCCP chunk contains:
|
||||
# Profile name 1-79 bytes (character string)
|
||||
|
@ -565,13 +581,13 @@ def _save(im, fp, filename, chunk=putchunk, check=0):
|
|||
p = ICCProfile.ICCProfile(im.info["icc_profile"])
|
||||
name = p.tags.desc.get("ASCII", p.tags.desc.get("Unicode", p.tags.desc.get("Macintosh", p.tags.desc.get("en", {}).get("US", "ICC Profile")))).encode("latin1", "replace")[:79]
|
||||
except ImportError:
|
||||
name = "ICC Profile"
|
||||
data = name + "\0\0" + zlib.compress(im.info["icc_profile"])
|
||||
chunk(fp, "iCCP", data)
|
||||
name = b"ICC Profile"
|
||||
data = name + b"\0\0" + zlib.compress(im.info["icc_profile"])
|
||||
chunk(fp, b"iCCP", data)
|
||||
|
||||
ImageFile._save(im, _idat(fp, chunk), [("zip", (0,0)+im.size, 0, rawmode)])
|
||||
|
||||
chunk(fp, "IEND", "")
|
||||
chunk(fp, b"IEND", b"")
|
||||
|
||||
try:
|
||||
fp.flush()
|
||||
|
@ -593,7 +609,7 @@ def getchunks(im, **params):
|
|||
self.data.append(chunk)
|
||||
|
||||
def append(fp, cid, *data):
|
||||
data = string.join(data, "")
|
||||
data = b"".join(data)
|
||||
hi, lo = Image.core.crc32(data, Image.core.crc32(cid))
|
||||
crc = o16(hi) + o16(lo)
|
||||
fp.append((cid, data, crc))
|
||||
|
|
|
@ -19,26 +19,28 @@ __version__ = "0.2"
|
|||
|
||||
import string
|
||||
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
b_whitespace = string.whitespace.encode()
|
||||
|
||||
MODES = {
|
||||
# standard
|
||||
"P4": "1",
|
||||
"P5": "L",
|
||||
"P6": "RGB",
|
||||
b"P4": "1",
|
||||
b"P5": "L",
|
||||
b"P6": "RGB",
|
||||
# extensions
|
||||
"P0CMYK": "CMYK",
|
||||
b"P0CMYK": "CMYK",
|
||||
# PIL extensions (for test purposes only)
|
||||
"PyP": "P",
|
||||
"PyRGBA": "RGBA",
|
||||
"PyCMYK": "CMYK"
|
||||
b"PyP": "P",
|
||||
b"PyRGBA": "RGBA",
|
||||
b"PyCMYK": "CMYK"
|
||||
}
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[0] == "P" and prefix[1] in "0456y"
|
||||
return prefix[0:1] == b"P" and prefix[1] in b"0456y"
|
||||
|
||||
##
|
||||
# Image plugin for PBM, PGM, and PPM images.
|
||||
|
@ -48,10 +50,10 @@ class PpmImageFile(ImageFile.ImageFile):
|
|||
format = "PPM"
|
||||
format_description = "Pbmplus image"
|
||||
|
||||
def _token(self, s = ""):
|
||||
while 1: # read until next whitespace
|
||||
def _token(self, s = b""):
|
||||
while True: # read until next whitespace
|
||||
c = self.fp.read(1)
|
||||
if not c or c in string.whitespace:
|
||||
if not c or c in b_whitespace:
|
||||
break
|
||||
s = s + c
|
||||
return s
|
||||
|
@ -60,8 +62,8 @@ class PpmImageFile(ImageFile.ImageFile):
|
|||
|
||||
# check magic
|
||||
s = self.fp.read(1)
|
||||
if s != "P":
|
||||
raise SyntaxError, "not a PPM file"
|
||||
if s != b"P":
|
||||
raise SyntaxError("not a PPM file")
|
||||
mode = MODES[self._token(s)]
|
||||
|
||||
if mode == "1":
|
||||
|
@ -71,12 +73,12 @@ class PpmImageFile(ImageFile.ImageFile):
|
|||
self.mode = rawmode = mode
|
||||
|
||||
for ix in range(3):
|
||||
while 1:
|
||||
while 1:
|
||||
while True:
|
||||
while True:
|
||||
s = self.fp.read(1)
|
||||
if s not in string.whitespace:
|
||||
if s not in b_whitespace:
|
||||
break
|
||||
if s != "#":
|
||||
if s != b"#":
|
||||
break
|
||||
s = self.fp.readline()
|
||||
s = int(self._token(s))
|
||||
|
@ -103,18 +105,18 @@ class PpmImageFile(ImageFile.ImageFile):
|
|||
|
||||
def _save(im, fp, filename):
|
||||
if im.mode == "1":
|
||||
rawmode, head = "1;I", "P4"
|
||||
rawmode, head = "1;I", b"P4"
|
||||
elif im.mode == "L":
|
||||
rawmode, head = "L", "P5"
|
||||
rawmode, head = "L", b"P5"
|
||||
elif im.mode == "RGB":
|
||||
rawmode, head = "RGB", "P6"
|
||||
rawmode, head = "RGB", b"P6"
|
||||
elif im.mode == "RGBA":
|
||||
rawmode, head = "RGB", "P6"
|
||||
rawmode, head = "RGB", b"P6"
|
||||
else:
|
||||
raise IOError, "cannot write mode %s as PPM" % im.mode
|
||||
fp.write(head + "\n%d %d\n" % im.size)
|
||||
if head != "P4":
|
||||
fp.write("255\n")
|
||||
raise IOError("cannot write mode %s as PPM" % im.mode)
|
||||
fp.write(head + ("\n%d %d\n" % im.size).encode('ascii'))
|
||||
if head != b"P4":
|
||||
fp.write(b"255\n")
|
||||
ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, 0, 1))])
|
||||
|
||||
# ALTERNATIVE: save via builtin debug function
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
__version__ = "0.4"
|
||||
|
||||
import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
MODES = {
|
||||
# (photoshop mode, bits) -> (pil mode, required channels)
|
||||
|
@ -36,17 +36,15 @@ MODES = {
|
|||
#
|
||||
# helpers
|
||||
|
||||
def i16(c):
|
||||
return ord(c[1]) + (ord(c[0])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16be
|
||||
i32 = _binary.i32be
|
||||
|
||||
# --------------------------------------------------------------------.
|
||||
# read PSD images
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] == "8BPS"
|
||||
return prefix[:4] == b"8BPS"
|
||||
|
||||
##
|
||||
# Image plugin for Photoshop images.
|
||||
|
@ -64,8 +62,8 @@ class PsdImageFile(ImageFile.ImageFile):
|
|||
# header
|
||||
|
||||
s = read(26)
|
||||
if s[:4] != "8BPS" or i16(s[4:]) != 1:
|
||||
raise SyntaxError, "not a PSD file"
|
||||
if s[:4] != b"8BPS" or i16(s[4:]) != 1:
|
||||
raise SyntaxError("not a PSD file")
|
||||
|
||||
psd_bits = i16(s[22:])
|
||||
psd_channels = i16(s[12:])
|
||||
|
@ -74,7 +72,7 @@ class PsdImageFile(ImageFile.ImageFile):
|
|||
mode, channels = MODES[(psd_mode, psd_bits)]
|
||||
|
||||
if channels > psd_channels:
|
||||
raise IOError, "not enough channels"
|
||||
raise IOError("not enough channels")
|
||||
|
||||
self.mode = mode
|
||||
self.size = i32(s[18:]), i32(s[14:])
|
||||
|
@ -100,7 +98,7 @@ class PsdImageFile(ImageFile.ImageFile):
|
|||
while self.fp.tell() < end:
|
||||
signature = read(4)
|
||||
id = i16(read(2))
|
||||
name = read(ord(read(1)))
|
||||
name = read(i8(read(1)))
|
||||
if not (len(name) & 1):
|
||||
read(1) # padding
|
||||
data = read(i32(read(4)))
|
||||
|
@ -146,7 +144,7 @@ class PsdImageFile(ImageFile.ImageFile):
|
|||
self.fp = self._fp
|
||||
return name, bbox
|
||||
except IndexError:
|
||||
raise EOFError, "no such layer"
|
||||
raise EOFError("no such layer")
|
||||
|
||||
def tell(self):
|
||||
# return layer number (0=image, 1..max=layers)
|
||||
|
@ -174,7 +172,7 @@ def _layerinfo(file):
|
|||
# image info
|
||||
info = []
|
||||
mode = []
|
||||
types = range(i16(read(2)))
|
||||
types = list(range(i16(read(2))))
|
||||
if len(types) > 4:
|
||||
continue
|
||||
|
||||
|
@ -219,9 +217,10 @@ def _layerinfo(file):
|
|||
file.seek(length, 1)
|
||||
combined += length + 4
|
||||
|
||||
length = ord(read(1))
|
||||
length = i8(read(1))
|
||||
if length:
|
||||
name = read(length)
|
||||
# Don't know the proper encoding, Latin-1 should be a good guess
|
||||
name = read(length).decode('latin-1', 'replace')
|
||||
combined += length + 1
|
||||
|
||||
file.seek(size - combined, 1)
|
||||
|
|
|
@ -21,14 +21,11 @@
|
|||
__version__ = "0.2"
|
||||
|
||||
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
|
||||
def i16(c):
|
||||
return ord(c[1]) + (ord(c[0])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16be
|
||||
i32 = _binary.i32be
|
||||
|
||||
|
||||
def _accept(prefix):
|
||||
|
@ -50,10 +47,10 @@ class SgiImageFile(ImageFile.ImageFile):
|
|||
raise SyntaxError("not an SGI image file")
|
||||
|
||||
# relevant header entries
|
||||
compression = ord(s[2])
|
||||
compression = i8(s[2])
|
||||
|
||||
# bytes, dimension, zsize
|
||||
layout = ord(s[3]), i16(s[4:]), i16(s[10:])
|
||||
layout = i8(s[3]), i16(s[4:]), i16(s[10:])
|
||||
|
||||
# determine mode from bytes/zsize
|
||||
if layout == (1, 2, 1) or layout == (1, 1, 1):
|
||||
|
|
|
@ -33,7 +33,9 @@
|
|||
# http://www.wadsworth.org/spider_doc/spider/docs/image_doc.html
|
||||
#
|
||||
|
||||
import Image, ImageFile
|
||||
from __future__ import print_function
|
||||
|
||||
from . import Image, ImageFile
|
||||
import os, struct, sys
|
||||
|
||||
def isInt(f):
|
||||
|
@ -101,14 +103,14 @@ class SpiderImageFile(ImageFile.ImageFile):
|
|||
t = struct.unpack('<27f',f) # little-endian
|
||||
hdrlen = isSpiderHeader(t)
|
||||
if hdrlen == 0:
|
||||
raise SyntaxError, "not a valid Spider file"
|
||||
raise SyntaxError("not a valid Spider file")
|
||||
except struct.error:
|
||||
raise SyntaxError, "not a valid Spider file"
|
||||
raise SyntaxError("not a valid Spider file")
|
||||
|
||||
h = (99,) + t # add 1 value : spider header index starts at 1
|
||||
iform = int(h[5])
|
||||
if iform != 1:
|
||||
raise SyntaxError, "not a Spider 2D image"
|
||||
raise SyntaxError("not a Spider 2D image")
|
||||
|
||||
self.size = int(h[12]), int(h[2]) # size in pixels (width, height)
|
||||
self.istack = int(h[24])
|
||||
|
@ -131,7 +133,7 @@ class SpiderImageFile(ImageFile.ImageFile):
|
|||
offset = hdrlen + self.stkoffset
|
||||
self.istack = 2 # So Image knows it's still a stack
|
||||
else:
|
||||
raise SyntaxError, "inconsistent stack header values"
|
||||
raise SyntaxError("inconsistent stack header values")
|
||||
|
||||
if self.bigendian:
|
||||
self.rawmode = "F;32BF"
|
||||
|
@ -154,7 +156,7 @@ class SpiderImageFile(ImageFile.ImageFile):
|
|||
if self.istack == 0:
|
||||
return
|
||||
if frame >= self.nimages:
|
||||
raise EOFError, "attempt to seek past end of file"
|
||||
raise EOFError("attempt to seek past end of file")
|
||||
self.stkoffset = self.hdrlen + frame * (self.hdrlen + self.imgbytes)
|
||||
self.fp = self.__fp
|
||||
self.fp.seek(self.stkoffset)
|
||||
|
@ -171,7 +173,7 @@ class SpiderImageFile(ImageFile.ImageFile):
|
|||
|
||||
# returns a ImageTk.PhotoImage object, after rescaling to 0..255
|
||||
def tkPhotoImage(self):
|
||||
import ImageTk
|
||||
from . import ImageTk
|
||||
return ImageTk.PhotoImage(self.convert2byte(), palette=256)
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -186,13 +188,13 @@ def loadImageSeries(filelist=None):
|
|||
imglist = []
|
||||
for img in filelist:
|
||||
if not os.path.exists(img):
|
||||
print "unable to find %s" % img
|
||||
print("unable to find %s" % img)
|
||||
continue
|
||||
try:
|
||||
im = Image.open(img).convert2byte()
|
||||
except:
|
||||
if not isSpiderImage(img):
|
||||
print img + " is not a Spider image file"
|
||||
print(img + " is not a Spider image file")
|
||||
continue
|
||||
im.info['filename'] = img
|
||||
imglist.append(im)
|
||||
|
@ -239,13 +241,13 @@ def _save(im, fp, filename):
|
|||
|
||||
hdr = makeSpiderHeader(im)
|
||||
if len(hdr) < 256:
|
||||
raise IOError, "Error creating Spider header"
|
||||
raise IOError("Error creating Spider header")
|
||||
|
||||
# write the SPIDER header
|
||||
try:
|
||||
fp = open(filename, 'wb')
|
||||
except:
|
||||
raise IOError, "Unable to open %s for writing" % filename
|
||||
raise IOError("Unable to open %s for writing" % filename)
|
||||
fp.writelines(hdr)
|
||||
|
||||
rawmode = "F;32NF" #32-bit native floating point
|
||||
|
@ -267,12 +269,12 @@ Image.register_save("SPIDER", _save_spider)
|
|||
if __name__ == "__main__":
|
||||
|
||||
if not sys.argv[1:]:
|
||||
print "Syntax: python SpiderImagePlugin.py Spiderimage [outfile]"
|
||||
print("Syntax: python SpiderImagePlugin.py Spiderimage [outfile]")
|
||||
sys.exit()
|
||||
|
||||
filename = sys.argv[1]
|
||||
if not isSpiderImage(filename):
|
||||
print "input image must be in Spider format"
|
||||
print("input image must be in Spider format")
|
||||
sys.exit()
|
||||
|
||||
outfile = ""
|
||||
|
@ -280,15 +282,15 @@ if __name__ == "__main__":
|
|||
outfile = sys.argv[2]
|
||||
|
||||
im = Image.open(filename)
|
||||
print "image: " + str(im)
|
||||
print "format: " + str(im.format)
|
||||
print "size: " + str(im.size)
|
||||
print "mode: " + str(im.mode)
|
||||
print "max, min: ",
|
||||
print im.getextrema()
|
||||
print("image: " + str(im))
|
||||
print("format: " + str(im.format))
|
||||
print("size: " + str(im.size))
|
||||
print("mode: " + str(im.mode))
|
||||
print("max, min: ", end=' ')
|
||||
print(im.getextrema())
|
||||
|
||||
if outfile != "":
|
||||
# perform some image operation
|
||||
im = im.transpose(Image.FLIP_LEFT_RIGHT)
|
||||
print "saving a flipped version of %s as %s " % (os.path.basename(filename), outfile)
|
||||
print("saving a flipped version of %s as %s " % (os.path.basename(filename), outfile))
|
||||
im.save(outfile, "SPIDER")
|
||||
|
|
|
@ -20,14 +20,10 @@
|
|||
__version__ = "0.3"
|
||||
|
||||
|
||||
import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
|
||||
def i16(c):
|
||||
return ord(c[1]) + (ord(c[0])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[3]) + (ord(c[2])<<8) + (ord(c[1])<<16) + (ord(c[0])<<24)
|
||||
i16 = _binary.i16be
|
||||
i32 = _binary.i32be
|
||||
|
||||
|
||||
def _accept(prefix):
|
||||
|
@ -46,7 +42,7 @@ class SunImageFile(ImageFile.ImageFile):
|
|||
# HEAD
|
||||
s = self.fp.read(32)
|
||||
if i32(s) != 0x59a66a95:
|
||||
raise SyntaxError, "not an SUN raster file"
|
||||
raise SyntaxError("not an SUN raster file")
|
||||
|
||||
offset = 32
|
||||
|
||||
|
@ -60,7 +56,7 @@ class SunImageFile(ImageFile.ImageFile):
|
|||
elif depth == 24:
|
||||
self.mode, rawmode = "RGB", "BGR"
|
||||
else:
|
||||
raise SyntaxError, "unsupported mode"
|
||||
raise SyntaxError("unsupported mode")
|
||||
|
||||
compression = i32(s[20:24])
|
||||
|
||||
|
@ -71,7 +67,7 @@ class SunImageFile(ImageFile.ImageFile):
|
|||
if self.mode == "L":
|
||||
self.mode = rawmode = "P"
|
||||
|
||||
stride = (((self.size[0] * depth + 7) / 8) + 3) & (~3)
|
||||
stride = (((self.size[0] * depth + 7) // 8) + 3) & (~3)
|
||||
|
||||
if compression == 1:
|
||||
self.tile = [("raw", (0,0)+self.size, offset, (rawmode, stride))]
|
||||
|
|
15
PIL/TarIO.py
15
PIL/TarIO.py
|
@ -14,8 +14,7 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
import ContainerIO
|
||||
import string
|
||||
from . import ContainerIO
|
||||
|
||||
##
|
||||
# A file object that provides read access to a given member of a TAR
|
||||
|
@ -33,20 +32,20 @@ class TarIO(ContainerIO.ContainerIO):
|
|||
|
||||
fh = open(tarfile, "rb")
|
||||
|
||||
while 1:
|
||||
while True:
|
||||
|
||||
s = fh.read(512)
|
||||
if len(s) != 512:
|
||||
raise IOError, "unexpected end of tar file"
|
||||
raise IOError("unexpected end of tar file")
|
||||
|
||||
name = s[:100]
|
||||
i = string.find(name, chr(0))
|
||||
name = s[:100].decode('utf-8')
|
||||
i = name.find('\0')
|
||||
if i == 0:
|
||||
raise IOError, "cannot find subfile"
|
||||
raise IOError("cannot find subfile")
|
||||
if i > 0:
|
||||
name = name[:i]
|
||||
|
||||
size = string.atoi(s[124:136], 8)
|
||||
size = int(s[124:135], 8)
|
||||
|
||||
if file == name:
|
||||
break
|
||||
|
|
|
@ -19,18 +19,16 @@
|
|||
|
||||
__version__ = "0.3"
|
||||
|
||||
import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# Read RGA file
|
||||
|
||||
def i16(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8)
|
||||
|
||||
def i32(c):
|
||||
return ord(c[0]) + (ord(c[1])<<8) + (ord(c[2])<<16) + (ord(c[3])<<24)
|
||||
i8 = _binary.i8
|
||||
i16 = _binary.i16le
|
||||
i32 = _binary.i32le
|
||||
|
||||
|
||||
MODES = {
|
||||
|
@ -45,7 +43,7 @@ MODES = {
|
|||
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[0] == "\0"
|
||||
return prefix[0:1] == b"\0"
|
||||
|
||||
##
|
||||
# Image plugin for Targa files.
|
||||
|
@ -60,14 +58,14 @@ class TgaImageFile(ImageFile.ImageFile):
|
|||
# process header
|
||||
s = self.fp.read(18)
|
||||
|
||||
id = ord(s[0])
|
||||
id = i8(s[0])
|
||||
|
||||
colormaptype = ord(s[1])
|
||||
imagetype = ord(s[2])
|
||||
colormaptype = i8(s[1])
|
||||
imagetype = i8(s[2])
|
||||
|
||||
depth = ord(s[16])
|
||||
depth = i8(s[16])
|
||||
|
||||
flags = ord(s[17])
|
||||
flags = i8(s[17])
|
||||
|
||||
self.size = i16(s[12:]), i16(s[14:])
|
||||
|
||||
|
@ -75,7 +73,7 @@ class TgaImageFile(ImageFile.ImageFile):
|
|||
if id != 0 or colormaptype not in (0, 1) or\
|
||||
self.size[0] <= 0 or self.size[1] <= 0 or\
|
||||
depth not in (1, 8, 16, 24, 32):
|
||||
raise SyntaxError, "not a TGA file"
|
||||
raise SyntaxError("not a TGA file")
|
||||
|
||||
# image mode
|
||||
if imagetype in (3, 11):
|
||||
|
@ -89,7 +87,7 @@ class TgaImageFile(ImageFile.ImageFile):
|
|||
if depth == 32:
|
||||
self.mode = "RGBA"
|
||||
else:
|
||||
raise SyntaxError, "unknown TGA mode"
|
||||
raise SyntaxError("unknown TGA mode")
|
||||
|
||||
# orientation
|
||||
orientation = flags & 0x30
|
||||
|
@ -98,7 +96,7 @@ class TgaImageFile(ImageFile.ImageFile):
|
|||
elif not orientation:
|
||||
orientation = -1
|
||||
else:
|
||||
raise SyntaxError, "unknown TGA orientation"
|
||||
raise SyntaxError("unknown TGA orientation")
|
||||
|
||||
self.info["orientation"] = orientation
|
||||
|
||||
|
@ -110,13 +108,13 @@ class TgaImageFile(ImageFile.ImageFile):
|
|||
start, size, mapdepth = i16(s[3:]), i16(s[5:]), i16(s[7:])
|
||||
if mapdepth == 16:
|
||||
self.palette = ImagePalette.raw("BGR;16",
|
||||
"\0"*2*start + self.fp.read(2*size))
|
||||
b"\0"*2*start + self.fp.read(2*size))
|
||||
elif mapdepth == 24:
|
||||
self.palette = ImagePalette.raw("BGR",
|
||||
"\0"*3*start + self.fp.read(3*size))
|
||||
b"\0"*3*start + self.fp.read(3*size))
|
||||
elif mapdepth == 32:
|
||||
self.palette = ImagePalette.raw("BGRA",
|
||||
"\0"*4*start + self.fp.read(4*size))
|
||||
b"\0"*4*start + self.fp.read(4*size))
|
||||
|
||||
# setup tile descriptor
|
||||
try:
|
||||
|
@ -135,11 +133,9 @@ class TgaImageFile(ImageFile.ImageFile):
|
|||
# --------------------------------------------------------------------
|
||||
# Write TGA file
|
||||
|
||||
def o16(i):
|
||||
return chr(i&255) + chr(i>>8&255)
|
||||
|
||||
def o32(i):
|
||||
return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255)
|
||||
o8 = _binary.o8
|
||||
o16 = _binary.o16le
|
||||
o32 = _binary.o32le
|
||||
|
||||
SAVE = {
|
||||
"1": ("1", 1, 0, 3),
|
||||
|
@ -173,18 +169,18 @@ def _save(im, fp, filename, check=0):
|
|||
if orientation > 0:
|
||||
flags = flags | 0x20
|
||||
|
||||
fp.write("\000" +
|
||||
chr(colormaptype) +
|
||||
chr(imagetype) +
|
||||
fp.write(b"\000" +
|
||||
o8(colormaptype) +
|
||||
o8(imagetype) +
|
||||
o16(colormapfirst) +
|
||||
o16(colormaplength) +
|
||||
chr(colormapentry) +
|
||||
o8(colormapentry) +
|
||||
o16(0) +
|
||||
o16(0) +
|
||||
o16(im.size[0]) +
|
||||
o16(im.size[1]) +
|
||||
chr(bits) +
|
||||
chr(flags))
|
||||
o8(bits) +
|
||||
o8(flags))
|
||||
|
||||
if colormaptype:
|
||||
fp.write(im.im.getpalette("RGB", "BGR"))
|
||||
|
|
|
@ -39,48 +39,42 @@
|
|||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
__version__ = "1.3.5"
|
||||
|
||||
import Image, ImageFile
|
||||
import ImagePalette
|
||||
from . import Image, ImageFile
|
||||
from . import ImagePalette
|
||||
from . import _binary
|
||||
|
||||
import array, string, sys
|
||||
import array, sys
|
||||
import collections
|
||||
import itertools
|
||||
|
||||
II = "II" # little-endian (intel-style)
|
||||
MM = "MM" # big-endian (motorola-style)
|
||||
II = b"II" # little-endian (intel-style)
|
||||
MM = b"MM" # big-endian (motorola-style)
|
||||
|
||||
try:
|
||||
if sys.byteorder == "little":
|
||||
native_prefix = II
|
||||
else:
|
||||
native_prefix = MM
|
||||
except AttributeError:
|
||||
if ord(array.array("i",[1]).tostring()[0]):
|
||||
native_prefix = II
|
||||
else:
|
||||
native_prefix = MM
|
||||
i8 = _binary.i8
|
||||
o8 = _binary.o8
|
||||
|
||||
if sys.byteorder == "little":
|
||||
native_prefix = II
|
||||
else:
|
||||
native_prefix = MM
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# Read TIFF files
|
||||
|
||||
def il16(c,o=0):
|
||||
return ord(c[o]) + (ord(c[o+1])<<8)
|
||||
def il32(c,o=0):
|
||||
return ord(c[o]) + (ord(c[o+1])<<8) + (ord(c[o+2])<<16) + (ord(c[o+3])<<24)
|
||||
def ol16(i):
|
||||
return chr(i&255) + chr(i>>8&255)
|
||||
def ol32(i):
|
||||
return chr(i&255) + chr(i>>8&255) + chr(i>>16&255) + chr(i>>24&255)
|
||||
il16 = _binary.i16le
|
||||
il32 = _binary.i32le
|
||||
ol16 = _binary.o16le
|
||||
ol32 = _binary.o32le
|
||||
|
||||
def ib16(c,o=0):
|
||||
return ord(c[o+1]) + (ord(c[o])<<8)
|
||||
def ib32(c,o=0):
|
||||
return ord(c[o+3]) + (ord(c[o+2])<<8) + (ord(c[o+1])<<16) + (ord(c[o])<<24)
|
||||
def ob16(i):
|
||||
return chr(i>>8&255) + chr(i&255)
|
||||
def ob32(i):
|
||||
return chr(i>>24&255) + chr(i>>16&255) + chr(i>>8&255) + chr(i&255)
|
||||
ib16 = _binary.i16be
|
||||
ib32 = _binary.i32be
|
||||
ob16 = _binary.o16be
|
||||
ob32 = _binary.o32be
|
||||
|
||||
# a few tag names, just to make the code below a bit more readable
|
||||
IMAGEWIDTH = 256
|
||||
|
@ -196,7 +190,7 @@ OPEN_INFO = {
|
|||
|
||||
}
|
||||
|
||||
PREFIXES = ["MM\000\052", "II\052\000", "II\xBC\000"]
|
||||
PREFIXES = [b"MM\000\052", b"II\052\000", b"II\xBC\000"]
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:4] in PREFIXES
|
||||
|
@ -204,7 +198,7 @@ def _accept(prefix):
|
|||
##
|
||||
# Wrapper for TIFF IFDs.
|
||||
|
||||
class ImageFileDirectory:
|
||||
class ImageFileDirectory(collections.MutableMapping):
|
||||
|
||||
# represents a TIFF tag directory. to speed things up,
|
||||
# we don't decode tags unless they're asked for.
|
||||
|
@ -227,16 +221,7 @@ class ImageFileDirectory:
|
|||
self.tagtype = {} # added 2008-06-05 by Florian Hoech
|
||||
self.next = None
|
||||
|
||||
# dictionary API (sort of)
|
||||
|
||||
def keys(self):
|
||||
return self.tagdata.keys() + self.tags.keys()
|
||||
|
||||
def items(self):
|
||||
items = self.tags.items()
|
||||
for tag in self.tagdata.keys():
|
||||
items.append((tag, self[tag]))
|
||||
return items
|
||||
# dictionary API
|
||||
|
||||
def __len__(self):
|
||||
return len(self.tagdata) + len(self.tags)
|
||||
|
@ -251,12 +236,6 @@ class ImageFileDirectory:
|
|||
del self.tagdata[tag]
|
||||
return data
|
||||
|
||||
def get(self, tag, default=None):
|
||||
try:
|
||||
return self[tag]
|
||||
except KeyError:
|
||||
return default
|
||||
|
||||
def getscalar(self, tag, default=None):
|
||||
try:
|
||||
value = self[tag]
|
||||
|
@ -265,36 +244,43 @@ class ImageFileDirectory:
|
|||
# work around broken (?) matrox library
|
||||
# (from Ted Wright, via Bob Klimek)
|
||||
raise KeyError # use default
|
||||
raise ValueError, "not a scalar"
|
||||
raise ValueError("not a scalar")
|
||||
return value[0]
|
||||
except KeyError:
|
||||
if default is None:
|
||||
raise
|
||||
return default
|
||||
|
||||
def has_key(self, tag):
|
||||
return self.tags.has_key(tag) or self.tagdata.has_key(tag)
|
||||
def __contains__(self, tag):
|
||||
return tag in self.tags or tag in self.tagdata
|
||||
|
||||
if bytes is str:
|
||||
def has_key(self, tag):
|
||||
return tag in self
|
||||
|
||||
def __setitem__(self, tag, value):
|
||||
if type(value) is not type(()):
|
||||
if not isinstance(value, tuple):
|
||||
value = (value,)
|
||||
self.tags[tag] = value
|
||||
|
||||
def __delitem__(self, tag):
|
||||
self.tags.pop(tag, self.tagdata.pop(tag, None))
|
||||
|
||||
def __iter__(self):
|
||||
return itertools.chain(self.tags.__iter__(), self.tagdata.__iter__())
|
||||
|
||||
# load primitives
|
||||
|
||||
load_dispatch = {}
|
||||
|
||||
def load_byte(self, data):
|
||||
l = []
|
||||
for i in range(len(data)):
|
||||
l.append(ord(data[i]))
|
||||
return tuple(l)
|
||||
return data
|
||||
load_dispatch[1] = (1, load_byte)
|
||||
|
||||
def load_string(self, data):
|
||||
if data[-1:] == '\0':
|
||||
if data[-1:] == b'\0':
|
||||
data = data[:-1]
|
||||
return data
|
||||
return data.decode('latin-1', 'replace')
|
||||
load_dispatch[2] = (1, load_string)
|
||||
|
||||
def load_short(self, data):
|
||||
|
@ -352,17 +338,17 @@ class ImageFileDirectory:
|
|||
tag, typ = i16(ifd), i16(ifd, 2)
|
||||
|
||||
if Image.DEBUG:
|
||||
import TiffTags
|
||||
from . import TiffTags
|
||||
tagname = TiffTags.TAGS.get(tag, "unknown")
|
||||
typname = TiffTags.TYPES.get(typ, "unknown")
|
||||
print "tag: %s (%d)" % (tagname, tag),
|
||||
print "- type: %s (%d)" % (typname, typ),
|
||||
print("tag: %s (%d)" % (tagname, tag), end=' ')
|
||||
print("- type: %s (%d)" % (typname, typ), end=' ')
|
||||
|
||||
try:
|
||||
dispatch = self.load_dispatch[typ]
|
||||
except KeyError:
|
||||
if Image.DEBUG:
|
||||
print "- unsupported type", typ
|
||||
print("- unsupported type", typ)
|
||||
continue # ignore unsupported type
|
||||
|
||||
size, handler = dispatch
|
||||
|
@ -379,16 +365,16 @@ class ImageFileDirectory:
|
|||
data = ifd[8:8+size]
|
||||
|
||||
if len(data) != size:
|
||||
raise IOError, "not enough data"
|
||||
raise IOError("not enough data")
|
||||
|
||||
self.tagdata[tag] = typ, data
|
||||
self.tagtype[tag] = typ
|
||||
|
||||
if Image.DEBUG:
|
||||
if tag in (COLORMAP, IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK, ICCPROFILE, XMP):
|
||||
print "- value: <table: %d bytes>" % size
|
||||
print("- value: <table: %d bytes>" % size)
|
||||
else:
|
||||
print "- value:", self[tag]
|
||||
print("- value:", self[tag])
|
||||
|
||||
self.next = i32(fp.read(4))
|
||||
|
||||
|
@ -402,8 +388,7 @@ class ImageFileDirectory:
|
|||
fp.write(o16(len(self.tags)))
|
||||
|
||||
# always write in ascending tag order
|
||||
tags = self.tags.items()
|
||||
tags.sort()
|
||||
tags = sorted(self.tags.items())
|
||||
|
||||
directory = []
|
||||
append = directory.append
|
||||
|
@ -417,19 +402,19 @@ class ImageFileDirectory:
|
|||
|
||||
typ = None
|
||||
|
||||
if self.tagtype.has_key(tag):
|
||||
if tag in self.tagtype:
|
||||
typ = self.tagtype[tag]
|
||||
|
||||
if typ == 1:
|
||||
# byte data
|
||||
data = value = string.join(map(chr, value), "")
|
||||
data = value
|
||||
elif typ == 7:
|
||||
# untyped data
|
||||
data = value = string.join(value, "")
|
||||
elif type(value[0]) is type(""):
|
||||
data = value = b"".join(value)
|
||||
elif isinstance(value[0], str):
|
||||
# string data
|
||||
typ = 2
|
||||
data = value = string.join(value, "\0") + "\0"
|
||||
data = value = b"\0".join(value.encode('ascii', 'replace')) + b"\0"
|
||||
else:
|
||||
# integer data
|
||||
if tag == STRIPOFFSETS:
|
||||
|
@ -444,31 +429,31 @@ class ImageFileDirectory:
|
|||
if v >= 65536:
|
||||
typ = 4
|
||||
if typ == 3:
|
||||
data = string.join(map(o16, value), "")
|
||||
data = b"".join(map(o16, value))
|
||||
else:
|
||||
data = string.join(map(o32, value), "")
|
||||
data = b"".join(map(o32, value))
|
||||
|
||||
if Image.DEBUG:
|
||||
import TiffTags
|
||||
from . import TiffTags
|
||||
tagname = TiffTags.TAGS.get(tag, "unknown")
|
||||
typname = TiffTags.TYPES.get(typ, "unknown")
|
||||
print "save: %s (%d)" % (tagname, tag),
|
||||
print "- type: %s (%d)" % (typname, typ),
|
||||
print("save: %s (%d)" % (tagname, tag), end=' ')
|
||||
print("- type: %s (%d)" % (typname, typ), end=' ')
|
||||
if tag in (COLORMAP, IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK, ICCPROFILE, XMP):
|
||||
size = len(data)
|
||||
print "- value: <table: %d bytes>" % size
|
||||
print("- value: <table: %d bytes>" % size)
|
||||
else:
|
||||
print "- value:", value
|
||||
print("- value:", value)
|
||||
|
||||
# figure out if data fits into the directory
|
||||
if len(data) == 4:
|
||||
append((tag, typ, len(value), data, ""))
|
||||
append((tag, typ, len(value), data, b""))
|
||||
elif len(data) < 4:
|
||||
append((tag, typ, len(value), data + (4-len(data))*"\0", ""))
|
||||
append((tag, typ, len(value), data + (4-len(data))*b"\0", b""))
|
||||
else:
|
||||
count = len(value)
|
||||
if typ == 5:
|
||||
count = count / 2 # adjust for rational data field
|
||||
count = count // 2 # adjust for rational data field
|
||||
append((tag, typ, count, o32(offset), data))
|
||||
offset = offset + len(data)
|
||||
if offset & 1:
|
||||
|
@ -484,17 +469,17 @@ class ImageFileDirectory:
|
|||
# pass 2: write directory to file
|
||||
for tag, typ, count, value, data in directory:
|
||||
if Image.DEBUG > 1:
|
||||
print tag, typ, count, repr(value), repr(data)
|
||||
print(tag, typ, count, repr(value), repr(data))
|
||||
fp.write(o16(tag) + o16(typ) + o32(count) + value)
|
||||
|
||||
# -- overwrite here for multi-page --
|
||||
fp.write("\0\0\0\0") # end of directory
|
||||
fp.write(b"\0\0\0\0") # end of directory
|
||||
|
||||
# pass 3: write auxiliary data to file
|
||||
for tag, typ, count, value, data in directory:
|
||||
fp.write(data)
|
||||
if len(data) & 1:
|
||||
fp.write("\0")
|
||||
fp.write(b"\0")
|
||||
|
||||
return offset
|
||||
|
||||
|
@ -513,7 +498,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
ifh = self.fp.read(8)
|
||||
|
||||
if ifh[:4] not in PREFIXES:
|
||||
raise SyntaxError, "not a TIFF file"
|
||||
raise SyntaxError("not a TIFF file")
|
||||
|
||||
# image file directory (tag dictionary)
|
||||
self.tag = self.ifd = ImageFileDirectory(ifh[:2])
|
||||
|
@ -547,7 +532,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
self.__next = self.__first
|
||||
while self.__frame < frame:
|
||||
if not self.__next:
|
||||
raise EOFError, "no more images in TIFF file"
|
||||
raise EOFError("no more images in TIFF file")
|
||||
self.fp.seek(self.__next)
|
||||
self.tag.load(self.fp)
|
||||
self.__next = self.tag.next
|
||||
|
@ -569,18 +554,18 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
args = (rawmode, 0, 1)
|
||||
elif compression == "jpeg":
|
||||
args = rawmode, ""
|
||||
if self.tag.has_key(JPEGTABLES):
|
||||
if JPEGTABLES in self.tag:
|
||||
# Hack to handle abbreviated JPEG headers
|
||||
self.tile_prefix = self.tag[JPEGTABLES]
|
||||
elif compression == "packbits":
|
||||
args = rawmode
|
||||
elif compression == "tiff_lzw":
|
||||
args = rawmode
|
||||
if self.tag.has_key(317):
|
||||
if 317 in self.tag:
|
||||
# Section 14: Differencing Predictor
|
||||
self.decoderconfig = (self.tag[PREDICTOR][0],)
|
||||
|
||||
if self.tag.has_key(ICCPROFILE):
|
||||
if ICCPROFILE in self.tag:
|
||||
self.info['icc_profile'] = self.tag[ICCPROFILE]
|
||||
|
||||
return args
|
||||
|
@ -588,8 +573,8 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
def _setup(self):
|
||||
"Setup this image object based on current tags"
|
||||
|
||||
if self.tag.has_key(0xBC01):
|
||||
raise IOError, "Windows Media Photo files not yet supported"
|
||||
if 0xBC01 in self.tag:
|
||||
raise IOError("Windows Media Photo files not yet supported")
|
||||
|
||||
getscalar = self.tag.getscalar
|
||||
|
||||
|
@ -604,11 +589,11 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
fillorder = getscalar(FILLORDER, 1)
|
||||
|
||||
if Image.DEBUG:
|
||||
print "*** Summary ***"
|
||||
print "- compression:", self._compression
|
||||
print "- photometric_interpretation:", photo
|
||||
print "- planar_configuration:", self._planar_configuration
|
||||
print "- fill_order:", fillorder
|
||||
print("*** Summary ***")
|
||||
print("- compression:", self._compression)
|
||||
print("- photometric_interpretation:", photo)
|
||||
print("- planar_configuration:", self._planar_configuration)
|
||||
print("- fill_order:", fillorder)
|
||||
|
||||
# size
|
||||
xsize = getscalar(IMAGEWIDTH)
|
||||
|
@ -616,7 +601,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
self.size = xsize, ysize
|
||||
|
||||
if Image.DEBUG:
|
||||
print "- size:", self.size
|
||||
print("- size:", self.size)
|
||||
|
||||
format = getscalar(SAMPLEFORMAT, 1)
|
||||
|
||||
|
@ -627,17 +612,17 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
self.tag.get(EXTRASAMPLES, ())
|
||||
)
|
||||
if Image.DEBUG:
|
||||
print "format key:", key
|
||||
print("format key:", key)
|
||||
try:
|
||||
self.mode, rawmode = OPEN_INFO[key]
|
||||
except KeyError:
|
||||
if Image.DEBUG:
|
||||
print "- unsupported format"
|
||||
raise SyntaxError, "unknown pixel mode"
|
||||
print("- unsupported format")
|
||||
raise SyntaxError("unknown pixel mode")
|
||||
|
||||
if Image.DEBUG:
|
||||
print "- raw mode:", rawmode
|
||||
print "- pil mode:", self.mode
|
||||
print("- raw mode:", rawmode)
|
||||
print("- pil mode:", self.mode)
|
||||
|
||||
self.info["compression"] = self._compression
|
||||
|
||||
|
@ -658,7 +643,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
# build tile descriptors
|
||||
x = y = l = 0
|
||||
self.tile = []
|
||||
if self.tag.has_key(STRIPOFFSETS):
|
||||
if STRIPOFFSETS in self.tag:
|
||||
# striped image
|
||||
h = getscalar(ROWSPERSTRIP, ysize)
|
||||
w = self.size[0]
|
||||
|
@ -675,7 +660,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
x = y = 0
|
||||
l = l + 1
|
||||
a = None
|
||||
elif self.tag.has_key(TILEOFFSETS):
|
||||
elif TILEOFFSETS in self.tag:
|
||||
# tiled image
|
||||
w = getscalar(322)
|
||||
h = getscalar(323)
|
||||
|
@ -698,14 +683,14 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
a = None
|
||||
else:
|
||||
if Image.DEBUG:
|
||||
print "- unsupported data organization"
|
||||
print("- unsupported data organization")
|
||||
raise SyntaxError("unknown data organization")
|
||||
|
||||
# fixup palette descriptor
|
||||
|
||||
if self.mode == "P":
|
||||
palette = map(lambda a: chr(a / 256), self.tag[COLORMAP])
|
||||
self.palette = ImagePalette.raw("RGB;L", string.join(palette, ""))
|
||||
palette = [o8(a // 256) for a in self.tag[COLORMAP]]
|
||||
self.palette = ImagePalette.raw("RGB;L", b"".join(palette))
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# Write TIFF files
|
||||
|
@ -738,10 +723,10 @@ SAVE_INFO = {
|
|||
|
||||
def _cvt_res(value):
|
||||
# convert value to TIFF rational number -- (numerator, denominator)
|
||||
if type(value) in (type([]), type(())):
|
||||
if isinstance(value, collections.Sequence):
|
||||
assert(len(value) % 2 == 0)
|
||||
return value
|
||||
if type(value) == type(1):
|
||||
if isinstance(value, int):
|
||||
return (value, 1)
|
||||
value = float(value)
|
||||
return (int(value * 65536), 65536)
|
||||
|
@ -751,7 +736,7 @@ def _save(im, fp, filename):
|
|||
try:
|
||||
rawmode, prefix, photo, format, bits, extra = SAVE_INFO[im.mode]
|
||||
except KeyError:
|
||||
raise IOError, "cannot write mode %s as TIFF" % im.mode
|
||||
raise IOError("cannot write mode %s as TIFF" % im.mode)
|
||||
|
||||
ifd = ImageFileDirectory(prefix)
|
||||
|
||||
|
@ -769,28 +754,28 @@ def _save(im, fp, filename):
|
|||
if hasattr(im, 'tag'):
|
||||
# preserve tags from original TIFF image file
|
||||
for key in (RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION):
|
||||
if im.tag.tagdata.has_key(key):
|
||||
if key in im.tag.tagdata:
|
||||
ifd[key] = im.tag.tagdata.get(key)
|
||||
# preserve some more tags from original TIFF image file
|
||||
# -- 2008-06-06 Florian Hoech
|
||||
ifd.tagtype = im.tag.tagtype
|
||||
for key in (IPTC_NAA_CHUNK, PHOTOSHOP_CHUNK, XMP):
|
||||
if im.tag.has_key(key):
|
||||
if key in im.tag:
|
||||
ifd[key] = im.tag[key]
|
||||
# preserve ICC profile (should also work when saving other formats
|
||||
# which support profiles as TIFF) -- 2008-06-06 Florian Hoech
|
||||
if im.info.has_key("icc_profile"):
|
||||
if "icc_profile" in im.info:
|
||||
ifd[ICCPROFILE] = im.info["icc_profile"]
|
||||
if im.encoderinfo.has_key("description"):
|
||||
if "description" in im.encoderinfo:
|
||||
ifd[IMAGEDESCRIPTION] = im.encoderinfo["description"]
|
||||
if im.encoderinfo.has_key("resolution"):
|
||||
if "resolution" in im.encoderinfo:
|
||||
ifd[X_RESOLUTION] = ifd[Y_RESOLUTION] \
|
||||
= _cvt_res(im.encoderinfo["resolution"])
|
||||
if im.encoderinfo.has_key("x resolution"):
|
||||
if "x resolution" in im.encoderinfo:
|
||||
ifd[X_RESOLUTION] = _cvt_res(im.encoderinfo["x resolution"])
|
||||
if im.encoderinfo.has_key("y resolution"):
|
||||
if "y resolution" in im.encoderinfo:
|
||||
ifd[Y_RESOLUTION] = _cvt_res(im.encoderinfo["y resolution"])
|
||||
if im.encoderinfo.has_key("resolution unit"):
|
||||
if "resolution unit" in im.encoderinfo:
|
||||
unit = im.encoderinfo["resolution unit"]
|
||||
if unit == "inch":
|
||||
ifd[RESOLUTION_UNIT] = 2
|
||||
|
@ -798,13 +783,13 @@ def _save(im, fp, filename):
|
|||
ifd[RESOLUTION_UNIT] = 3
|
||||
else:
|
||||
ifd[RESOLUTION_UNIT] = 1
|
||||
if im.encoderinfo.has_key("software"):
|
||||
if "software" in im.encoderinfo:
|
||||
ifd[SOFTWARE] = im.encoderinfo["software"]
|
||||
if im.encoderinfo.has_key("date time"):
|
||||
if "date time" in im.encoderinfo:
|
||||
ifd[DATE_TIME] = im.encoderinfo["date time"]
|
||||
if im.encoderinfo.has_key("artist"):
|
||||
if "artist" in im.encoderinfo:
|
||||
ifd[ARTIST] = im.encoderinfo["artist"]
|
||||
if im.encoderinfo.has_key("copyright"):
|
||||
if "copyright" in im.encoderinfo:
|
||||
ifd[COPYRIGHT] = im.encoderinfo["copyright"]
|
||||
|
||||
dpi = im.encoderinfo.get("dpi")
|
||||
|
@ -826,10 +811,10 @@ def _save(im, fp, filename):
|
|||
|
||||
if im.mode == "P":
|
||||
lut = im.im.getpalette("RGB", "RGB;L")
|
||||
ifd[COLORMAP] = tuple(map(lambda v: ord(v) * 256, lut))
|
||||
ifd[COLORMAP] = tuple(i8(v) * 256 for v in lut)
|
||||
|
||||
# data orientation
|
||||
stride = len(bits) * ((im.size[0]*bits[0]+7)/8)
|
||||
stride = len(bits) * ((im.size[0]*bits[0]+7)//8)
|
||||
ifd[ROWSPERSTRIP] = im.size[1]
|
||||
ifd[STRIPBYTECOUNTS] = stride * im.size[1]
|
||||
ifd[STRIPOFFSETS] = 0 # this is adjusted by IFD writer
|
||||
|
@ -843,7 +828,7 @@ def _save(im, fp, filename):
|
|||
|
||||
|
||||
# -- helper for multi-page save --
|
||||
if im.encoderinfo.has_key("_debug_multipage"):
|
||||
if "_debug_multipage" in im.encoderinfo:
|
||||
#just to access o32 and o16 (using correct byte order)
|
||||
im._debug_multipage = ifd
|
||||
|
||||
|
|
|
@ -21,10 +21,17 @@
|
|||
# http://www.flipcode.com/tutorials/tut_q2levels.shtml
|
||||
# and has been tested with a few sample files found using google.
|
||||
|
||||
import Image
|
||||
from __future__ import print_function
|
||||
|
||||
def i32(c, o=0):
|
||||
return ord(c[o])+(ord(c[o+1])<<8)+(ord(c[o+2])<<16)+(ord(c[o+3])<<24)
|
||||
from . import Image, _binary
|
||||
|
||||
try:
|
||||
import builtins
|
||||
except ImportError:
|
||||
import __builtin__
|
||||
builtins = __builtin__
|
||||
|
||||
i32 = _binary.i32le
|
||||
|
||||
##
|
||||
# Load texture from a Quake2 WAL texture file.
|
||||
|
@ -42,8 +49,7 @@ def open(filename):
|
|||
if hasattr(filename, "read"):
|
||||
fp = filename
|
||||
else:
|
||||
import __builtin__
|
||||
fp = __builtin__.open(filename, "rb")
|
||||
fp = builtins.open(filename, "rb")
|
||||
|
||||
# read header fields
|
||||
header = fp.read(32+24+32+12)
|
||||
|
@ -53,15 +59,15 @@ def open(filename):
|
|||
# load pixel data
|
||||
fp.seek(offset)
|
||||
|
||||
im = Image.fromstring("P", size, fp.read(size[0] * size[1]))
|
||||
im = Image.frombytes("P", size, fp.read(size[0] * size[1]))
|
||||
im.putpalette(quake2palette)
|
||||
|
||||
im.format = "WAL"
|
||||
im.format_description = "Quake2 Texture"
|
||||
|
||||
# strings are null-terminated
|
||||
im.info["name"] = header[:32].split("\0", 1)[0]
|
||||
next_name = header[56:56+32].split("\0", 1)[0]
|
||||
im.info["name"] = header[:32].split(b"\0", 1)[0]
|
||||
next_name = header[56:56+32].split(b"\0", 1)[0]
|
||||
if next_name:
|
||||
im.info["next_name"] = next_name
|
||||
|
||||
|
@ -70,57 +76,57 @@ def open(filename):
|
|||
|
||||
quake2palette = (
|
||||
# default palette taken from piffo 0.93 by Hans Häggström
|
||||
"\x01\x01\x01\x0b\x0b\x0b\x12\x12\x12\x17\x17\x17\x1b\x1b\x1b\x1e"
|
||||
"\x1e\x1e\x22\x22\x22\x26\x26\x26\x29\x29\x29\x2c\x2c\x2c\x2f\x2f"
|
||||
"\x2f\x32\x32\x32\x35\x35\x35\x37\x37\x37\x3a\x3a\x3a\x3c\x3c\x3c"
|
||||
"\x24\x1e\x13\x22\x1c\x12\x20\x1b\x12\x1f\x1a\x10\x1d\x19\x10\x1b"
|
||||
"\x17\x0f\x1a\x16\x0f\x18\x14\x0d\x17\x13\x0d\x16\x12\x0d\x14\x10"
|
||||
"\x0b\x13\x0f\x0b\x10\x0d\x0a\x0f\x0b\x0a\x0d\x0b\x07\x0b\x0a\x07"
|
||||
"\x23\x23\x26\x22\x22\x25\x22\x20\x23\x21\x1f\x22\x20\x1e\x20\x1f"
|
||||
"\x1d\x1e\x1d\x1b\x1c\x1b\x1a\x1a\x1a\x19\x19\x18\x17\x17\x17\x16"
|
||||
"\x16\x14\x14\x14\x13\x13\x13\x10\x10\x10\x0f\x0f\x0f\x0d\x0d\x0d"
|
||||
"\x2d\x28\x20\x29\x24\x1c\x27\x22\x1a\x25\x1f\x17\x38\x2e\x1e\x31"
|
||||
"\x29\x1a\x2c\x25\x17\x26\x20\x14\x3c\x30\x14\x37\x2c\x13\x33\x28"
|
||||
"\x12\x2d\x24\x10\x28\x1f\x0f\x22\x1a\x0b\x1b\x14\x0a\x13\x0f\x07"
|
||||
"\x31\x1a\x16\x30\x17\x13\x2e\x16\x10\x2c\x14\x0d\x2a\x12\x0b\x27"
|
||||
"\x0f\x0a\x25\x0f\x07\x21\x0d\x01\x1e\x0b\x01\x1c\x0b\x01\x1a\x0b"
|
||||
"\x01\x18\x0a\x01\x16\x0a\x01\x13\x0a\x01\x10\x07\x01\x0d\x07\x01"
|
||||
"\x29\x23\x1e\x27\x21\x1c\x26\x20\x1b\x25\x1f\x1a\x23\x1d\x19\x21"
|
||||
"\x1c\x18\x20\x1b\x17\x1e\x19\x16\x1c\x18\x14\x1b\x17\x13\x19\x14"
|
||||
"\x10\x17\x13\x0f\x14\x10\x0d\x12\x0f\x0b\x0f\x0b\x0a\x0b\x0a\x07"
|
||||
"\x26\x1a\x0f\x23\x19\x0f\x20\x17\x0f\x1c\x16\x0f\x19\x13\x0d\x14"
|
||||
"\x10\x0b\x10\x0d\x0a\x0b\x0a\x07\x33\x22\x1f\x35\x29\x26\x37\x2f"
|
||||
"\x2d\x39\x35\x34\x37\x39\x3a\x33\x37\x39\x30\x34\x36\x2b\x31\x34"
|
||||
"\x27\x2e\x31\x22\x2b\x2f\x1d\x28\x2c\x17\x25\x2a\x0f\x20\x26\x0d"
|
||||
"\x1e\x25\x0b\x1c\x22\x0a\x1b\x20\x07\x19\x1e\x07\x17\x1b\x07\x14"
|
||||
"\x18\x01\x12\x16\x01\x0f\x12\x01\x0b\x0d\x01\x07\x0a\x01\x01\x01"
|
||||
"\x2c\x21\x21\x2a\x1f\x1f\x29\x1d\x1d\x27\x1c\x1c\x26\x1a\x1a\x24"
|
||||
"\x18\x18\x22\x17\x17\x21\x16\x16\x1e\x13\x13\x1b\x12\x12\x18\x10"
|
||||
"\x10\x16\x0d\x0d\x12\x0b\x0b\x0d\x0a\x0a\x0a\x07\x07\x01\x01\x01"
|
||||
"\x2e\x30\x29\x2d\x2e\x27\x2b\x2c\x26\x2a\x2a\x24\x28\x29\x23\x27"
|
||||
"\x27\x21\x26\x26\x1f\x24\x24\x1d\x22\x22\x1c\x1f\x1f\x1a\x1c\x1c"
|
||||
"\x18\x19\x19\x16\x17\x17\x13\x13\x13\x10\x0f\x0f\x0d\x0b\x0b\x0a"
|
||||
"\x30\x1e\x1b\x2d\x1c\x19\x2c\x1a\x17\x2a\x19\x14\x28\x17\x13\x26"
|
||||
"\x16\x10\x24\x13\x0f\x21\x12\x0d\x1f\x10\x0b\x1c\x0f\x0a\x19\x0d"
|
||||
"\x0a\x16\x0b\x07\x12\x0a\x07\x0f\x07\x01\x0a\x01\x01\x01\x01\x01"
|
||||
"\x28\x29\x38\x26\x27\x36\x25\x26\x34\x24\x24\x31\x22\x22\x2f\x20"
|
||||
"\x21\x2d\x1e\x1f\x2a\x1d\x1d\x27\x1b\x1b\x25\x19\x19\x21\x17\x17"
|
||||
"\x1e\x14\x14\x1b\x13\x12\x17\x10\x0f\x13\x0d\x0b\x0f\x0a\x07\x07"
|
||||
"\x2f\x32\x29\x2d\x30\x26\x2b\x2e\x24\x29\x2c\x21\x27\x2a\x1e\x25"
|
||||
"\x28\x1c\x23\x26\x1a\x21\x25\x18\x1e\x22\x14\x1b\x1f\x10\x19\x1c"
|
||||
"\x0d\x17\x1a\x0a\x13\x17\x07\x10\x13\x01\x0d\x0f\x01\x0a\x0b\x01"
|
||||
"\x01\x3f\x01\x13\x3c\x0b\x1b\x39\x10\x20\x35\x14\x23\x31\x17\x23"
|
||||
"\x2d\x18\x23\x29\x18\x3f\x3f\x3f\x3f\x3f\x39\x3f\x3f\x31\x3f\x3f"
|
||||
"\x2a\x3f\x3f\x20\x3f\x3f\x14\x3f\x3c\x12\x3f\x39\x0f\x3f\x35\x0b"
|
||||
"\x3f\x32\x07\x3f\x2d\x01\x3d\x2a\x01\x3b\x26\x01\x39\x21\x01\x37"
|
||||
"\x1d\x01\x34\x1a\x01\x32\x16\x01\x2f\x12\x01\x2d\x0f\x01\x2a\x0b"
|
||||
"\x01\x27\x07\x01\x23\x01\x01\x1d\x01\x01\x17\x01\x01\x10\x01\x01"
|
||||
"\x3d\x01\x01\x19\x19\x3f\x3f\x01\x01\x01\x01\x3f\x16\x16\x13\x10"
|
||||
"\x10\x0f\x0d\x0d\x0b\x3c\x2e\x2a\x36\x27\x20\x30\x21\x18\x29\x1b"
|
||||
"\x10\x3c\x39\x37\x37\x32\x2f\x31\x2c\x28\x2b\x26\x21\x30\x22\x20"
|
||||
b"\x01\x01\x01\x0b\x0b\x0b\x12\x12\x12\x17\x17\x17\x1b\x1b\x1b\x1e"
|
||||
b"\x1e\x1e\x22\x22\x22\x26\x26\x26\x29\x29\x29\x2c\x2c\x2c\x2f\x2f"
|
||||
b"\x2f\x32\x32\x32\x35\x35\x35\x37\x37\x37\x3a\x3a\x3a\x3c\x3c\x3c"
|
||||
b"\x24\x1e\x13\x22\x1c\x12\x20\x1b\x12\x1f\x1a\x10\x1d\x19\x10\x1b"
|
||||
b"\x17\x0f\x1a\x16\x0f\x18\x14\x0d\x17\x13\x0d\x16\x12\x0d\x14\x10"
|
||||
b"\x0b\x13\x0f\x0b\x10\x0d\x0a\x0f\x0b\x0a\x0d\x0b\x07\x0b\x0a\x07"
|
||||
b"\x23\x23\x26\x22\x22\x25\x22\x20\x23\x21\x1f\x22\x20\x1e\x20\x1f"
|
||||
b"\x1d\x1e\x1d\x1b\x1c\x1b\x1a\x1a\x1a\x19\x19\x18\x17\x17\x17\x16"
|
||||
b"\x16\x14\x14\x14\x13\x13\x13\x10\x10\x10\x0f\x0f\x0f\x0d\x0d\x0d"
|
||||
b"\x2d\x28\x20\x29\x24\x1c\x27\x22\x1a\x25\x1f\x17\x38\x2e\x1e\x31"
|
||||
b"\x29\x1a\x2c\x25\x17\x26\x20\x14\x3c\x30\x14\x37\x2c\x13\x33\x28"
|
||||
b"\x12\x2d\x24\x10\x28\x1f\x0f\x22\x1a\x0b\x1b\x14\x0a\x13\x0f\x07"
|
||||
b"\x31\x1a\x16\x30\x17\x13\x2e\x16\x10\x2c\x14\x0d\x2a\x12\x0b\x27"
|
||||
b"\x0f\x0a\x25\x0f\x07\x21\x0d\x01\x1e\x0b\x01\x1c\x0b\x01\x1a\x0b"
|
||||
b"\x01\x18\x0a\x01\x16\x0a\x01\x13\x0a\x01\x10\x07\x01\x0d\x07\x01"
|
||||
b"\x29\x23\x1e\x27\x21\x1c\x26\x20\x1b\x25\x1f\x1a\x23\x1d\x19\x21"
|
||||
b"\x1c\x18\x20\x1b\x17\x1e\x19\x16\x1c\x18\x14\x1b\x17\x13\x19\x14"
|
||||
b"\x10\x17\x13\x0f\x14\x10\x0d\x12\x0f\x0b\x0f\x0b\x0a\x0b\x0a\x07"
|
||||
b"\x26\x1a\x0f\x23\x19\x0f\x20\x17\x0f\x1c\x16\x0f\x19\x13\x0d\x14"
|
||||
b"\x10\x0b\x10\x0d\x0a\x0b\x0a\x07\x33\x22\x1f\x35\x29\x26\x37\x2f"
|
||||
b"\x2d\x39\x35\x34\x37\x39\x3a\x33\x37\x39\x30\x34\x36\x2b\x31\x34"
|
||||
b"\x27\x2e\x31\x22\x2b\x2f\x1d\x28\x2c\x17\x25\x2a\x0f\x20\x26\x0d"
|
||||
b"\x1e\x25\x0b\x1c\x22\x0a\x1b\x20\x07\x19\x1e\x07\x17\x1b\x07\x14"
|
||||
b"\x18\x01\x12\x16\x01\x0f\x12\x01\x0b\x0d\x01\x07\x0a\x01\x01\x01"
|
||||
b"\x2c\x21\x21\x2a\x1f\x1f\x29\x1d\x1d\x27\x1c\x1c\x26\x1a\x1a\x24"
|
||||
b"\x18\x18\x22\x17\x17\x21\x16\x16\x1e\x13\x13\x1b\x12\x12\x18\x10"
|
||||
b"\x10\x16\x0d\x0d\x12\x0b\x0b\x0d\x0a\x0a\x0a\x07\x07\x01\x01\x01"
|
||||
b"\x2e\x30\x29\x2d\x2e\x27\x2b\x2c\x26\x2a\x2a\x24\x28\x29\x23\x27"
|
||||
b"\x27\x21\x26\x26\x1f\x24\x24\x1d\x22\x22\x1c\x1f\x1f\x1a\x1c\x1c"
|
||||
b"\x18\x19\x19\x16\x17\x17\x13\x13\x13\x10\x0f\x0f\x0d\x0b\x0b\x0a"
|
||||
b"\x30\x1e\x1b\x2d\x1c\x19\x2c\x1a\x17\x2a\x19\x14\x28\x17\x13\x26"
|
||||
b"\x16\x10\x24\x13\x0f\x21\x12\x0d\x1f\x10\x0b\x1c\x0f\x0a\x19\x0d"
|
||||
b"\x0a\x16\x0b\x07\x12\x0a\x07\x0f\x07\x01\x0a\x01\x01\x01\x01\x01"
|
||||
b"\x28\x29\x38\x26\x27\x36\x25\x26\x34\x24\x24\x31\x22\x22\x2f\x20"
|
||||
b"\x21\x2d\x1e\x1f\x2a\x1d\x1d\x27\x1b\x1b\x25\x19\x19\x21\x17\x17"
|
||||
b"\x1e\x14\x14\x1b\x13\x12\x17\x10\x0f\x13\x0d\x0b\x0f\x0a\x07\x07"
|
||||
b"\x2f\x32\x29\x2d\x30\x26\x2b\x2e\x24\x29\x2c\x21\x27\x2a\x1e\x25"
|
||||
b"\x28\x1c\x23\x26\x1a\x21\x25\x18\x1e\x22\x14\x1b\x1f\x10\x19\x1c"
|
||||
b"\x0d\x17\x1a\x0a\x13\x17\x07\x10\x13\x01\x0d\x0f\x01\x0a\x0b\x01"
|
||||
b"\x01\x3f\x01\x13\x3c\x0b\x1b\x39\x10\x20\x35\x14\x23\x31\x17\x23"
|
||||
b"\x2d\x18\x23\x29\x18\x3f\x3f\x3f\x3f\x3f\x39\x3f\x3f\x31\x3f\x3f"
|
||||
b"\x2a\x3f\x3f\x20\x3f\x3f\x14\x3f\x3c\x12\x3f\x39\x0f\x3f\x35\x0b"
|
||||
b"\x3f\x32\x07\x3f\x2d\x01\x3d\x2a\x01\x3b\x26\x01\x39\x21\x01\x37"
|
||||
b"\x1d\x01\x34\x1a\x01\x32\x16\x01\x2f\x12\x01\x2d\x0f\x01\x2a\x0b"
|
||||
b"\x01\x27\x07\x01\x23\x01\x01\x1d\x01\x01\x17\x01\x01\x10\x01\x01"
|
||||
b"\x3d\x01\x01\x19\x19\x3f\x3f\x01\x01\x01\x01\x3f\x16\x16\x13\x10"
|
||||
b"\x10\x0f\x0d\x0d\x0b\x3c\x2e\x2a\x36\x27\x20\x30\x21\x18\x29\x1b"
|
||||
b"\x10\x3c\x39\x37\x37\x32\x2f\x31\x2c\x28\x2b\x26\x21\x30\x22\x20"
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
im = open("../hacks/sample.wal")
|
||||
print im.info, im.mode, im.size
|
||||
print(im.info, im.mode, im.size)
|
||||
im.save("../out.png")
|
||||
|
|
|
@ -17,10 +17,13 @@
|
|||
|
||||
__version__ = "0.2"
|
||||
|
||||
import Image, ImageFile
|
||||
from . import Image, ImageFile, _binary
|
||||
|
||||
_handler = None
|
||||
|
||||
if str != bytes:
|
||||
long = int
|
||||
|
||||
##
|
||||
# Install application-specific WMF image handler.
|
||||
#
|
||||
|
@ -41,7 +44,7 @@ if hasattr(Image.core, "drawwmf"):
|
|||
|
||||
def load(self, im):
|
||||
im.fp.seek(0) # rewind
|
||||
return Image.fromstring(
|
||||
return Image.frombytes(
|
||||
"RGB", im.size,
|
||||
Image.core.drawwmf(im.fp.read(), im.size, self.bbox),
|
||||
"raw", "BGR", (im.size[0]*3 + 3) & -4, -1
|
||||
|
@ -51,20 +54,15 @@ if hasattr(Image.core, "drawwmf"):
|
|||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def word(c, o=0):
|
||||
return ord(c[o]) + (ord(c[o+1])<<8)
|
||||
word = _binary.i16le
|
||||
|
||||
def short(c, o=0):
|
||||
v = ord(c[o]) + (ord(c[o+1])<<8)
|
||||
v = word(c, o)
|
||||
if v >= 32768:
|
||||
v = v - 65536
|
||||
return v
|
||||
|
||||
def dword(c, o=0):
|
||||
return ord(c[o]) + (ord(c[o+1])<<8) + (ord(c[o+2])<<16) + (ord(c[o+3])<<24)
|
||||
|
||||
def long(c, o=0):
|
||||
return dword(c, o)
|
||||
dword = _binary.i32le
|
||||
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -72,8 +70,8 @@ def long(c, o=0):
|
|||
|
||||
def _accept(prefix):
|
||||
return (
|
||||
prefix[:6] == "\xd7\xcd\xc6\x9a\x00\x00" or
|
||||
prefix[:4] == "\x01\x00\x00\x00"
|
||||
prefix[:6] == b"\xd7\xcd\xc6\x9a\x00\x00" or
|
||||
prefix[:4] == b"\x01\x00\x00\x00"
|
||||
)
|
||||
|
||||
##
|
||||
|
@ -89,7 +87,7 @@ class WmfStubImageFile(ImageFile.StubImageFile):
|
|||
# check placable header
|
||||
s = self.fp.read(80)
|
||||
|
||||
if s[:6] == "\xd7\xcd\xc6\x9a\x00\x00":
|
||||
if s[:6] == b"\xd7\xcd\xc6\x9a\x00\x00":
|
||||
|
||||
# placeable windows metafile
|
||||
|
||||
|
@ -101,7 +99,7 @@ class WmfStubImageFile(ImageFile.StubImageFile):
|
|||
x1 = short(s, 10); y1 = short(s, 12)
|
||||
|
||||
# normalize size to 72 dots per inch
|
||||
size = (x1 - x0) * 72 / inch, (y1 - y0) * 72 / inch
|
||||
size = (x1 - x0) * 72 // inch, (y1 - y0) * 72 // inch
|
||||
|
||||
self.info["wmf_bbox"] = x0, y0, x1, y1
|
||||
|
||||
|
@ -110,25 +108,25 @@ class WmfStubImageFile(ImageFile.StubImageFile):
|
|||
# print self.mode, self.size, self.info
|
||||
|
||||
# sanity check (standard metafile header)
|
||||
if s[22:26] != "\x01\x00\t\x00":
|
||||
if s[22:26] != b"\x01\x00\t\x00":
|
||||
raise SyntaxError("Unsupported WMF file format")
|
||||
|
||||
elif long(s) == 1 and s[40:44] == " EMF":
|
||||
elif dword(s) == 1 and s[40:44] == b" EMF":
|
||||
# enhanced metafile
|
||||
|
||||
# get bounding box
|
||||
x0 = long(s, 8); y0 = long(s, 12)
|
||||
x1 = long(s, 16); y1 = long(s, 20)
|
||||
x0 = dword(s, 8); y0 = dword(s, 12)
|
||||
x1 = dword(s, 16); y1 = dword(s, 20)
|
||||
|
||||
# get frame (in 0.01 millimeter units)
|
||||
frame = long(s, 24), long(s, 28), long(s, 32), long(s, 36)
|
||||
frame = dword(s, 24), dword(s, 28), dword(s, 32), dword(s, 36)
|
||||
|
||||
# normalize size to 72 dots per inch
|
||||
size = x1 - x0, y1 - y0
|
||||
|
||||
# calculate dots per inch from bbox and frame
|
||||
xdpi = 2540 * (x1 - y0) / (frame[2] - frame[0])
|
||||
ydpi = 2540 * (y1 - y0) / (frame[3] - frame[1])
|
||||
xdpi = 2540 * (x1 - y0) // (frame[2] - frame[0])
|
||||
ydpi = 2540 * (y1 - y0) // (frame[3] - frame[1])
|
||||
|
||||
self.info["wmf_bbox"] = x0, y0, x1, y1
|
||||
|
||||
|
|
|
@ -19,15 +19,16 @@
|
|||
|
||||
__version__ = "0.1"
|
||||
|
||||
import string
|
||||
import Image, ImageFile, ImagePalette
|
||||
from . import Image, ImageFile, ImagePalette, _binary
|
||||
|
||||
o8 = _binary.o8
|
||||
|
||||
# standard color palette for thumbnails (RGB332)
|
||||
PALETTE = ""
|
||||
PALETTE = b""
|
||||
for r in range(8):
|
||||
for g in range(8):
|
||||
for b in range(4):
|
||||
PALETTE = PALETTE + (chr((r*255)/7)+chr((g*255)/7)+chr((b*255)/3))
|
||||
PALETTE = PALETTE + (o8((r*255)//7)+o8((g*255)//7)+o8((b*255)//3))
|
||||
|
||||
##
|
||||
# Image plugin for XV thumbnail images.
|
||||
|
@ -41,25 +42,25 @@ class XVThumbImageFile(ImageFile.ImageFile):
|
|||
|
||||
# check magic
|
||||
s = self.fp.read(6)
|
||||
if s != "P7 332":
|
||||
raise SyntaxError, "not an XV thumbnail file"
|
||||
if s != b"P7 332":
|
||||
raise SyntaxError("not an XV thumbnail file")
|
||||
|
||||
# Skip to beginning of next line
|
||||
self.fp.readline()
|
||||
|
||||
# skip info comments
|
||||
while 1:
|
||||
while True:
|
||||
s = self.fp.readline()
|
||||
if not s:
|
||||
raise SyntaxError, "Unexpected EOF reading XV thumbnail file"
|
||||
if s[0] != '#':
|
||||
raise SyntaxError("Unexpected EOF reading XV thumbnail file")
|
||||
if s[0] != b'#':
|
||||
break
|
||||
|
||||
# parse header line (already read)
|
||||
s = string.split(s.strip())
|
||||
s = s.strip().split()
|
||||
|
||||
self.mode = "P"
|
||||
self.size = int(s[0]), int(s[1])
|
||||
self.size = int(s[0:1]), int(s[1:2])
|
||||
|
||||
self.palette = ImagePalette.raw("RGB", PALETTE)
|
||||
|
||||
|
|
|
@ -21,22 +21,22 @@
|
|||
|
||||
__version__ = "0.6"
|
||||
|
||||
import re, string
|
||||
import Image, ImageFile
|
||||
import re
|
||||
from . import Image, ImageFile
|
||||
|
||||
# XBM header
|
||||
xbm_head = re.compile(
|
||||
"\s*#define[ \t]+[^_]*_width[ \t]+(?P<width>[0-9]+)[\r\n]+"
|
||||
"#define[ \t]+[^_]*_height[ \t]+(?P<height>[0-9]+)[\r\n]+"
|
||||
"(?P<hotspot>"
|
||||
"#define[ \t]+[^_]*_x_hot[ \t]+(?P<xhot>[0-9]+)[\r\n]+"
|
||||
"#define[ \t]+[^_]*_y_hot[ \t]+(?P<yhot>[0-9]+)[\r\n]+"
|
||||
")?"
|
||||
"[\\000-\\377]*_bits\\[\\]"
|
||||
b"\s*#define[ \t]+[^_]*_width[ \t]+(?P<width>[0-9]+)[\r\n]+"
|
||||
b"#define[ \t]+[^_]*_height[ \t]+(?P<height>[0-9]+)[\r\n]+"
|
||||
b"(?P<hotspot>"
|
||||
b"#define[ \t]+[^_]*_x_hot[ \t]+(?P<xhot>[0-9]+)[\r\n]+"
|
||||
b"#define[ \t]+[^_]*_y_hot[ \t]+(?P<yhot>[0-9]+)[\r\n]+"
|
||||
b")?"
|
||||
b"[\\000-\\377]*_bits\\[\\]"
|
||||
)
|
||||
|
||||
def _accept(prefix):
|
||||
return string.lstrip(prefix)[:7] == "#define"
|
||||
return prefix.lstrip()[:7] == b"#define"
|
||||
|
||||
##
|
||||
# Image plugin for X11 bitmaps.
|
||||
|
@ -69,21 +69,21 @@ class XbmImageFile(ImageFile.ImageFile):
|
|||
def _save(im, fp, filename):
|
||||
|
||||
if im.mode != "1":
|
||||
raise IOError, "cannot write mode %s as XBM" % im.mode
|
||||
raise IOError("cannot write mode %s as XBM" % im.mode)
|
||||
|
||||
fp.write("#define im_width %d\n" % im.size[0])
|
||||
fp.write("#define im_height %d\n" % im.size[1])
|
||||
fp.write(("#define im_width %d\n" % im.size[0]).encode('ascii'))
|
||||
fp.write(("#define im_height %d\n" % im.size[1]).encode('ascii'))
|
||||
|
||||
hotspot = im.encoderinfo.get("hotspot")
|
||||
if hotspot:
|
||||
fp.write("#define im_x_hot %d\n" % hotspot[0])
|
||||
fp.write("#define im_y_hot %d\n" % hotspot[1])
|
||||
fp.write(("#define im_x_hot %d\n" % hotspot[0]).encode('ascii'))
|
||||
fp.write(("#define im_y_hot %d\n" % hotspot[1]).encode('ascii'))
|
||||
|
||||
fp.write("static char im_bits[] = {\n")
|
||||
fp.write(b"static char im_bits[] = {\n")
|
||||
|
||||
ImageFile._save(im, fp, [("xbm", (0,0)+im.size, 0, None)])
|
||||
|
||||
fp.write("};\n")
|
||||
fp.write(b"};\n")
|
||||
|
||||
|
||||
Image.register_open("XBM", XbmImageFile, _accept)
|
||||
|
|
|
@ -18,15 +18,16 @@
|
|||
__version__ = "0.2"
|
||||
|
||||
|
||||
import re, string
|
||||
import Image, ImageFile, ImagePalette
|
||||
import re
|
||||
from . import Image, ImageFile, ImagePalette
|
||||
from ._binary import i8, o8
|
||||
|
||||
# XPM header
|
||||
xpm_head = re.compile("\"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)")
|
||||
xpm_head = re.compile(b"\"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)")
|
||||
|
||||
|
||||
def _accept(prefix):
|
||||
return prefix[:9] == "/* XPM */"
|
||||
return prefix[:9] == b"/* XPM */"
|
||||
|
||||
##
|
||||
# Image plugin for X11 pixel maps.
|
||||
|
@ -39,13 +40,13 @@ class XpmImageFile(ImageFile.ImageFile):
|
|||
def _open(self):
|
||||
|
||||
if not _accept(self.fp.read(9)):
|
||||
raise SyntaxError, "not an XPM file"
|
||||
raise SyntaxError("not an XPM file")
|
||||
|
||||
# skip forward to next string
|
||||
while 1:
|
||||
while True:
|
||||
s = self.fp.readline()
|
||||
if not s:
|
||||
raise SyntaxError, "broken XPM file"
|
||||
raise SyntaxError("broken XPM file")
|
||||
m = xpm_head.match(s)
|
||||
if m:
|
||||
break
|
||||
|
@ -56,50 +57,50 @@ class XpmImageFile(ImageFile.ImageFile):
|
|||
bpp = int(m.group(4))
|
||||
|
||||
if pal > 256 or bpp != 1:
|
||||
raise ValueError, "cannot read this XPM file"
|
||||
raise ValueError("cannot read this XPM file")
|
||||
|
||||
#
|
||||
# load palette description
|
||||
|
||||
palette = ["\0\0\0"] * 256
|
||||
palette = [b"\0\0\0"] * 256
|
||||
|
||||
for i in range(pal):
|
||||
|
||||
s = self.fp.readline()
|
||||
if s[-2:] == '\r\n':
|
||||
if s[-2:] == b'\r\n':
|
||||
s = s[:-2]
|
||||
elif s[-1:] in '\r\n':
|
||||
elif s[-1:] in b'\r\n':
|
||||
s = s[:-1]
|
||||
|
||||
c = ord(s[1])
|
||||
s = string.split(s[2:-2])
|
||||
c = i8(s[1])
|
||||
s = s[2:-2].split()
|
||||
|
||||
for i in range(0, len(s), 2):
|
||||
|
||||
if s[i] == "c":
|
||||
if s[i] == b"c":
|
||||
|
||||
# process colour key
|
||||
rgb = s[i+1]
|
||||
if rgb == "None":
|
||||
if rgb == b"None":
|
||||
self.info["transparency"] = c
|
||||
elif rgb[0] == "#":
|
||||
elif rgb[0:1] == b"#":
|
||||
# FIXME: handle colour names (see ImagePalette.py)
|
||||
rgb = string.atoi(rgb[1:], 16)
|
||||
palette[c] = chr((rgb >> 16) & 255) +\
|
||||
chr((rgb >> 8) & 255) +\
|
||||
chr(rgb & 255)
|
||||
rgb = int(rgb[1:], 16)
|
||||
palette[c] = o8((rgb >> 16) & 255) +\
|
||||
o8((rgb >> 8) & 255) +\
|
||||
o8(rgb & 255)
|
||||
else:
|
||||
# unknown colour
|
||||
raise ValueError, "cannot read this XPM file"
|
||||
raise ValueError("cannot read this XPM file")
|
||||
break
|
||||
|
||||
else:
|
||||
|
||||
# missing colour key
|
||||
raise ValueError, "cannot read this XPM file"
|
||||
raise ValueError("cannot read this XPM file")
|
||||
|
||||
self.mode = "P"
|
||||
self.palette = ImagePalette.raw("RGB", string.join(palette, ""))
|
||||
self.palette = ImagePalette.raw("RGB", b"".join(palette))
|
||||
|
||||
self.tile = [("raw", (0, 0)+self.size, self.fp.tell(), ("P", 0, 1))]
|
||||
|
||||
|
@ -113,11 +114,11 @@ class XpmImageFile(ImageFile.ImageFile):
|
|||
s = [None] * ysize
|
||||
|
||||
for i in range(ysize):
|
||||
s[i] = string.ljust(self.fp.readline()[1:xsize+1], xsize)
|
||||
s[i] = self.fp.readline()[1:xsize+1].ljust(xsize)
|
||||
|
||||
self.fp = None
|
||||
|
||||
return string.join(s, "")
|
||||
return b"".join(s)
|
||||
|
||||
#
|
||||
# Registry
|
||||
|
|
52
PIL/_binary.py
Normal file
52
PIL/_binary.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# Binary input/output support routines.
|
||||
#
|
||||
# Copyright (c) 1997-2003 by Secret Labs AB
|
||||
# Copyright (c) 1995-2003 by Fredrik Lundh
|
||||
# Copyright (c) 2012 by Brian Crowell
|
||||
#
|
||||
# See the README file for information on usage and redistribution.
|
||||
#
|
||||
|
||||
if bytes is str:
|
||||
def i8(c):
|
||||
return ord(c)
|
||||
|
||||
def o8(i):
|
||||
return chr(i&255)
|
||||
else:
|
||||
def i8(c):
|
||||
return c if c.__class__ is int else c[0]
|
||||
|
||||
def o8(i):
|
||||
return bytes((i&255,))
|
||||
|
||||
# Input, le = little endian, be = big endian
|
||||
def i16le(c, o=0):
|
||||
return i8(c[o]) | (i8(c[o+1])<<8)
|
||||
|
||||
def i32le(c, o=0):
|
||||
return i8(c[o]) | (i8(c[o+1])<<8) | (i8(c[o+2])<<16) | (i8(c[o+3])<<24)
|
||||
|
||||
def i16be(c, o=0):
|
||||
return (i8(c[o])<<8) | i8(c[o+1])
|
||||
|
||||
def i32be(c, o=0):
|
||||
return (i8(c[o])<<24) | (i8(c[o+1])<<16) | (i8(c[o+2])<<8) | i8(c[o+3])
|
||||
|
||||
# Output, le = little endian, be = big endian
|
||||
def o16le(i):
|
||||
return o8(i) + o8(i>>8)
|
||||
|
||||
def o32le(i):
|
||||
return o8(i) + o8(i>>8) + o8(i>>16) + o8(i>>24)
|
||||
|
||||
def o16be(i):
|
||||
return o8(i>>8) + o8(i)
|
||||
|
||||
def o32be(i):
|
||||
return o8(i>>24) + o8(i>>16) + o8(i>>8) + o8(i)
|
||||
|
134
Sane/_sane.c
134
Sane/_sane.c
|
@ -28,6 +28,12 @@ PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
#include <sys/time.h>
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
#define PyInt_AsLong PyLong_AsLong
|
||||
#define PyInt_FromLong PyLong_FromLong
|
||||
#define PyInt_Check PyLong_Check
|
||||
#endif
|
||||
|
||||
static PyObject *ErrorObject;
|
||||
|
||||
typedef struct {
|
||||
|
@ -51,14 +57,18 @@ PySane_Error(SANE_Status st)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
staticforward PyTypeObject SaneDev_Type;
|
||||
static PyTypeObject SaneDev_Type;
|
||||
|
||||
#define SaneDevObject_Check(v) ((v)->ob_type == &SaneDev_Type)
|
||||
#define SaneDevObject_Check(v) (Py_TYPE(v) == &SaneDev_Type)
|
||||
|
||||
static SaneDevObject *
|
||||
newSaneDevObject(void)
|
||||
{
|
||||
SaneDevObject *self;
|
||||
|
||||
if (PyType_Ready(&SaneDev_Type) < 0)
|
||||
return NULL;
|
||||
|
||||
self = PyObject_NEW(SaneDevObject, &SaneDev_Type);
|
||||
if (self == NULL)
|
||||
return NULL;
|
||||
|
@ -233,7 +243,11 @@ SaneDev_get_options(SaneDevObject *self, PyObject *args)
|
|||
constraint=PyList_New(0);
|
||||
for(j=0; d->constraint.string_list[j]!=NULL; j++)
|
||||
PyList_Append(constraint,
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyUnicode_DecodeLatin1(d->constraint.string_list[j], strlen(d->constraint.string_list[j]), NULL));
|
||||
#else
|
||||
PyString_FromString(d->constraint.string_list[j]));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
value=Py_BuildValue("isssiiiiO", i, d->name, d->title, d->desc,
|
||||
|
@ -284,7 +298,11 @@ SaneDev_get_option(SaneDevObject *self, PyObject *args)
|
|||
value=Py_BuildValue("d", SANE_UNFIX((*((SANE_Fixed*)v))) );
|
||||
break;
|
||||
case(SANE_TYPE_STRING):
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
value=PyUnicode_DecodeLatin1((const char *) v, strlen((const char *) v), NULL);
|
||||
#else
|
||||
value=Py_BuildValue("s", v);
|
||||
#endif
|
||||
break;
|
||||
case(SANE_TYPE_BUTTON):
|
||||
case(SANE_TYPE_GROUP):
|
||||
|
@ -345,7 +363,25 @@ SaneDev_set_option(SaneDevObject *self, PyObject *args)
|
|||
*( (SANE_Fixed*)v) = SANE_FIX(PyFloat_AsDouble(value));
|
||||
break;
|
||||
case(SANE_TYPE_STRING):
|
||||
if (!PyString_Check(value))
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
if (!PyUnicode_Check(value))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "SANE_STRING requires a string");
|
||||
free(v);
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
PyObject *encoded = PyUnicode_AsLatin1String(value);
|
||||
|
||||
if (!encoded)
|
||||
return NULL;
|
||||
|
||||
strncpy(v, PyBytes_AsString(encoded), d->size-1);
|
||||
((char*)v)[d->size-1] = 0;
|
||||
Py_DECREF(encoded);
|
||||
}
|
||||
#else
|
||||
if (!PyString_Check(value))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "SANE_STRING requires a string");
|
||||
free(v);
|
||||
|
@ -353,6 +389,7 @@ SaneDev_set_option(SaneDevObject *self, PyObject *args)
|
|||
}
|
||||
strncpy(v, PyString_AsString(value), d->size-1);
|
||||
((char*)v)[d->size-1] = 0;
|
||||
#endif
|
||||
break;
|
||||
case(SANE_TYPE_BUTTON):
|
||||
case(SANE_TYPE_GROUP):
|
||||
|
@ -1095,29 +1132,38 @@ static PyMethodDef SaneDev_methods[] = {
|
|||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
SaneDev_getattr(SaneDevObject *self, char *name)
|
||||
{
|
||||
return Py_FindMethod(SaneDev_methods, (PyObject *)self, name);
|
||||
}
|
||||
|
||||
staticforward PyTypeObject SaneDev_Type = {
|
||||
PyObject_HEAD_INIT(&PyType_Type)
|
||||
0, /*ob_size*/
|
||||
static PyTypeObject SaneDev_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"SaneDev", /*tp_name*/
|
||||
sizeof(SaneDevObject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
(destructor)SaneDev_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
(getattrfunc)SaneDev_getattr, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash*/
|
||||
0, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
0, /*tp_repr*/
|
||||
0, /*tp_as_number */
|
||||
0, /*tp_as_sequence */
|
||||
0, /*tp_as_mapping */
|
||||
0, /*tp_hash*/
|
||||
0, /*tp_call*/
|
||||
0, /*tp_str*/
|
||||
0, /*tp_getattro*/
|
||||
0, /*tp_setattro*/
|
||||
0, /*tp_as_buffer*/
|
||||
Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
||||
0, /*tp_doc*/
|
||||
0, /*tp_traverse*/
|
||||
0, /*tp_clear*/
|
||||
0, /*tp_richcompare*/
|
||||
0, /*tp_weaklistoffset*/
|
||||
0, /*tp_iter*/
|
||||
0, /*tp_iternext*/
|
||||
SaneDev_methods, /*tp_methods*/
|
||||
0, /*tp_members*/
|
||||
0, /*tp_getset*/
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
@ -1152,8 +1198,8 @@ PySane_exit(PyObject *self, PyObject *args)
|
|||
static PyObject *
|
||||
PySane_get_devices(PyObject *self, PyObject *args)
|
||||
{
|
||||
SANE_Device **devlist;
|
||||
SANE_Device *dev;
|
||||
const SANE_Device **devlist;
|
||||
const SANE_Device *dev;
|
||||
SANE_Status st;
|
||||
PyObject *list;
|
||||
int local_only, i;
|
||||
|
@ -1163,7 +1209,9 @@ PySane_get_devices(PyObject *self, PyObject *args)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
st=sane_get_devices(&devlist, local_only);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (st) return PySane_Error(st);
|
||||
if (!(list = PyList_New(0)))
|
||||
return NULL;
|
||||
|
@ -1191,7 +1239,9 @@ PySane_open(PyObject *self, PyObject *args)
|
|||
rv = newSaneDevObject();
|
||||
if ( rv == NULL )
|
||||
return NULL;
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
st = sane_open(name, &(rv->h));
|
||||
Py_END_ALLOW_THREADS
|
||||
if (st)
|
||||
{
|
||||
Py_DECREF(rv);
|
||||
|
@ -1248,17 +1298,40 @@ insint(PyObject *d, char *name, int value)
|
|||
Py_DECREF(v);
|
||||
}
|
||||
|
||||
void
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
static struct PyModuleDef PySane_moduledef = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"_sane",
|
||||
NULL,
|
||||
0,
|
||||
PySane_methods,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit__sane(void)
|
||||
{
|
||||
/* Create the module and add the functions */
|
||||
PyObject *m = PyModule_Create(&PySane_moduledef);
|
||||
if(!m)
|
||||
return NULL;
|
||||
#else /* if PY_MAJOR_VERSION < 3 */
|
||||
|
||||
PyMODINIT_FUNC
|
||||
init_sane(void)
|
||||
{
|
||||
PyObject *m, *d;
|
||||
|
||||
/* Create the module and add the functions */
|
||||
m = Py_InitModule("_sane", PySane_methods);
|
||||
/* Create the module and add the functions */
|
||||
PyObject *m = Py_InitModule("_sane", PySane_methods);
|
||||
if(!m)
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* Add some symbolic constants to the module */
|
||||
d = PyModule_GetDict(m);
|
||||
ErrorObject = PyString_FromString("_sane.error");
|
||||
PyObject *d = PyModule_GetDict(m);
|
||||
ErrorObject = PyErr_NewException("_sane.error", NULL, NULL);
|
||||
PyDict_SetItemString(d, "error", ErrorObject);
|
||||
|
||||
insint(d, "INFO_INEXACT", SANE_INFO_INEXACT);
|
||||
|
@ -1322,4 +1395,7 @@ init_sane(void)
|
|||
NUMARRAY_IMPORTED = 1;
|
||||
|
||||
#endif /* WITH_NUMARRAY */
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
return m;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
# Shows how to scan a 16 bit grayscale image into a numarray object
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
# Get the path set up to find PIL modules if not installed yet:
|
||||
import sys ; sys.path.append('../PIL')
|
||||
|
||||
|
@ -14,17 +16,17 @@ import Image
|
|||
def toImage(arr):
|
||||
if arr.type().bytes == 1:
|
||||
# need to swap coordinates btw array and image (with [::-1])
|
||||
im = Image.fromstring('L', arr.shape[::-1], arr.tostring())
|
||||
im = Image.frombytes('L', arr.shape[::-1], arr.tostring())
|
||||
else:
|
||||
arr_c = arr - arr.min()
|
||||
arr_c *= (255./arr_c.max())
|
||||
arr = arr_c.astype(UInt8)
|
||||
# need to swap coordinates btw array and image (with [::-1])
|
||||
im = Image.fromstring('L', arr.shape[::-1], arr.tostring())
|
||||
im = Image.frombytes('L', arr.shape[::-1], arr.tostring())
|
||||
return im
|
||||
|
||||
print 'SANE version:', sane.init()
|
||||
print 'Available devices=', sane.get_devices()
|
||||
print('SANE version:', sane.init())
|
||||
print('Available devices=', sane.get_devices())
|
||||
|
||||
s = sane.open(sane.get_devices()[0][0])
|
||||
|
||||
|
@ -32,7 +34,7 @@ s = sane.open(sane.get_devices()[0][0])
|
|||
s.mode = 'gray'
|
||||
s.br_x=320. ; s.br_y=240.
|
||||
|
||||
print 'Device parameters:', s.get_parameters()
|
||||
print('Device parameters:', s.get_parameters())
|
||||
|
||||
s.depth=16
|
||||
arr16 = s.arr_scan()
|
||||
|
|
|
@ -4,19 +4,21 @@
|
|||
# Shows how to scan a color image into a PIL rgb-image
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
# Get the path set up to find PIL modules if not installed yet:
|
||||
import sys ; sys.path.append('../PIL')
|
||||
|
||||
import sane
|
||||
print 'SANE version:', sane.init()
|
||||
print 'Available devices=', sane.get_devices()
|
||||
print('SANE version:', sane.init())
|
||||
print('Available devices=', sane.get_devices())
|
||||
|
||||
s = sane.open(sane.get_devices()[0][0])
|
||||
|
||||
s.mode = 'color'
|
||||
s.br_x=320. ; s.br_y=240.
|
||||
|
||||
print 'Device parameters:', s.get_parameters()
|
||||
print('Device parameters:', s.get_parameters())
|
||||
|
||||
# Initiate the scan
|
||||
s.start()
|
||||
|
|
31
Sane/sane.py
31
Sane/sane.py
|
@ -46,7 +46,6 @@ class Option:
|
|||
"""
|
||||
|
||||
def __init__(self, args, scanDev):
|
||||
import string
|
||||
self.scanDev = scanDev # needed to get current value of this option
|
||||
self.index, self.name = args[0], args[1]
|
||||
self.title, self.desc = args[2], args[3]
|
||||
|
@ -56,8 +55,8 @@ class Option:
|
|||
def f(x):
|
||||
if x=='-': return '_'
|
||||
else: return x
|
||||
if type(self.name)!=type(''): self.py_name=str(self.name)
|
||||
else: self.py_name=string.join(map(f, self.name), '')
|
||||
if not isinstance(self.name, str): self.py_name=str(self.name)
|
||||
else: self.py_name=''.join(map(f, self.name))
|
||||
|
||||
def is_active(self):
|
||||
return _sane.OPTION_IS_ACTIVE(self.cap)
|
||||
|
@ -86,7 +85,7 @@ active: %s
|
|||
settable: %s\n""" % (self.py_name, curValue,
|
||||
self.index, self.title, self.desc,
|
||||
TYPE_STR[self.type], UNIT_STR[self.unit],
|
||||
`self.constraint`, active, settable)
|
||||
repr(self.constraint), active, settable)
|
||||
return s
|
||||
|
||||
|
||||
|
@ -106,7 +105,7 @@ class _SaneIterator:
|
|||
def next(self):
|
||||
try:
|
||||
self.device.start()
|
||||
except error, v:
|
||||
except error as v:
|
||||
if v == 'Document feeder out of documents':
|
||||
raise StopIteration
|
||||
else:
|
||||
|
@ -166,16 +165,16 @@ class SaneDev:
|
|||
def __setattr__(self, key, value):
|
||||
dev=self.__dict__['dev']
|
||||
optdict=self.__dict__['opt']
|
||||
if not optdict.has_key(key):
|
||||
if key not in optdict:
|
||||
self.__dict__[key]=value ; return
|
||||
opt=optdict[key]
|
||||
if opt.type==TYPE_GROUP:
|
||||
raise AttributeError, "Groups can't be set: "+key
|
||||
raise AttributeError("Groups can't be set: "+key)
|
||||
if not _sane.OPTION_IS_ACTIVE(opt.cap):
|
||||
raise AttributeError, 'Inactive option: '+key
|
||||
raise AttributeError('Inactive option: '+key)
|
||||
if not _sane.OPTION_IS_SETTABLE(opt.cap):
|
||||
raise AttributeError, "Option can't be set by software: "+key
|
||||
if type(value) == int and opt.type == TYPE_FIXED:
|
||||
raise AttributeError("Option can't be set by software: "+key)
|
||||
if isinstance(value, int) and opt.type == TYPE_FIXED:
|
||||
# avoid annoying errors of backend if int is given instead float:
|
||||
value = float(value)
|
||||
self.last_opt = dev.set_option(opt.index, value)
|
||||
|
@ -187,18 +186,18 @@ class SaneDev:
|
|||
dev=self.__dict__['dev']
|
||||
optdict=self.__dict__['opt']
|
||||
if key=='optlist':
|
||||
return self.opt.keys()
|
||||
return list(self.opt.keys())
|
||||
if key=='area':
|
||||
return (self.tl_x, self.tl_y),(self.br_x, self.br_y)
|
||||
if not optdict.has_key(key):
|
||||
raise AttributeError, 'No such attribute: '+key
|
||||
if key not in optdict:
|
||||
raise AttributeError('No such attribute: '+key)
|
||||
opt=optdict[key]
|
||||
if opt.type==TYPE_BUTTON:
|
||||
raise AttributeError, "Buttons don't have values: "+key
|
||||
raise AttributeError("Buttons don't have values: "+key)
|
||||
if opt.type==TYPE_GROUP:
|
||||
raise AttributeError, "Groups don't have values: "+key
|
||||
raise AttributeError("Groups don't have values: "+key)
|
||||
if not _sane.OPTION_IS_ACTIVE(opt.cap):
|
||||
raise AttributeError, 'Inactive option: '+key
|
||||
raise AttributeError('Inactive option: '+key)
|
||||
value = dev.get_option(opt.index)
|
||||
return value
|
||||
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
# drag the slider to modify the image.
|
||||
#
|
||||
|
||||
from Tkinter import *
|
||||
try:
|
||||
from tkinter import *
|
||||
except ImportError:
|
||||
from Tkinter import *
|
||||
|
||||
from PIL import Image, ImageTk, ImageEnhance
|
||||
import sys
|
||||
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
# split an animation into a number of frame files
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from PIL import Image
|
||||
import os, string, sys
|
||||
import os, sys
|
||||
|
||||
class Interval:
|
||||
|
||||
|
@ -18,23 +20,23 @@ class Interval:
|
|||
|
||||
self.hilo = []
|
||||
|
||||
for s in string.split(interval, ","):
|
||||
if not string.strip(s):
|
||||
for s in interval.split(","):
|
||||
if not s.strip():
|
||||
continue
|
||||
try:
|
||||
v = string.atoi(s)
|
||||
v = int(s)
|
||||
if v < 0:
|
||||
lo, hi = 0, -v
|
||||
else:
|
||||
lo = hi = v
|
||||
except ValueError:
|
||||
i = string.find(s, "-")
|
||||
lo, hi = string.atoi(s[:i]), string.atoi(s[i+1:])
|
||||
i = s.find("-")
|
||||
lo, hi = int(s[:i]), int(s[i+1:])
|
||||
|
||||
self.hilo.append((hi, lo))
|
||||
|
||||
if not self.hilo:
|
||||
self.hilo = [(sys.maxint, 0)]
|
||||
self.hilo = [(sys.maxsize, 0)]
|
||||
|
||||
def __getitem__(self, index):
|
||||
|
||||
|
@ -53,23 +55,23 @@ if sys.argv[1:2] == ["-h"]:
|
|||
del sys.argv[1]
|
||||
|
||||
if not sys.argv[2:]:
|
||||
print
|
||||
print "Syntax: python explode.py infile template [range]"
|
||||
print
|
||||
print "The template argument is used to construct the names of the"
|
||||
print "individual frame files. The frames are numbered file001.ext,"
|
||||
print "file002.ext, etc. You can insert %d to control the placement"
|
||||
print "and syntax of the frame number."
|
||||
print
|
||||
print "The optional range argument specifies which frames to extract."
|
||||
print "You can give one or more ranges like 1-10, 5, -15 etc. If"
|
||||
print "omitted, all frames are extracted."
|
||||
print()
|
||||
print("Syntax: python explode.py infile template [range]")
|
||||
print()
|
||||
print("The template argument is used to construct the names of the")
|
||||
print("individual frame files. The frames are numbered file001.ext,")
|
||||
print("file002.ext, etc. You can insert %d to control the placement")
|
||||
print("and syntax of the frame number.")
|
||||
print()
|
||||
print("The optional range argument specifies which frames to extract.")
|
||||
print("You can give one or more ranges like 1-10, 5, -15 etc. If")
|
||||
print("omitted, all frames are extracted.")
|
||||
sys.exit(1)
|
||||
|
||||
infile = sys.argv[1]
|
||||
outfile = sys.argv[2]
|
||||
|
||||
frames = Interval(string.join(sys.argv[3:], ","))
|
||||
frames = Interval(",".join(sys.argv[3:]))
|
||||
|
||||
try:
|
||||
# check if outfile contains a placeholder
|
||||
|
@ -87,11 +89,11 @@ if html:
|
|||
html = open(file+".html", "w")
|
||||
html.write("<html>\n<body>\n")
|
||||
|
||||
while 1:
|
||||
while True:
|
||||
|
||||
if frames[ix]:
|
||||
im.save(outfile % ix)
|
||||
print outfile % ix
|
||||
print(outfile % ix)
|
||||
|
||||
if html:
|
||||
html.write("<img src='%s'><br>\n" % outfile % ix)
|
||||
|
|
|
@ -39,8 +39,9 @@
|
|||
# write data directly to a socket. Or something...
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from PIL import Image, ImageChops
|
||||
import string
|
||||
|
||||
from PIL.GifImagePlugin import getheader, getdata
|
||||
|
||||
|
@ -128,8 +129,8 @@ if __name__ == "__main__":
|
|||
import sys
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
print "GIFMAKER -- create GIF animations"
|
||||
print "Usage: gifmaker infile outfile"
|
||||
print("GIFMAKER -- create GIF animations")
|
||||
print("Usage: gifmaker infile outfile")
|
||||
sys.exit(1)
|
||||
|
||||
compress(sys.argv[1], sys.argv[2])
|
||||
|
|
|
@ -8,7 +8,11 @@
|
|||
# the image into a set of tiles.
|
||||
#
|
||||
|
||||
from Tkinter import *
|
||||
try:
|
||||
from tkinter import *
|
||||
except ImportError:
|
||||
from Tkinter import *
|
||||
|
||||
from PIL import Image, ImageTk
|
||||
import sys
|
||||
|
||||
|
|
|
@ -13,27 +13,29 @@
|
|||
# 0.5 98-12-30 fl Fixed -f option (from Anthony Baxter)
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import site
|
||||
import getopt, string, sys
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def usage():
|
||||
print "PIL Convert 0.5/1998-12-30 -- convert image files"
|
||||
print "Usage: pilconvert [option] infile outfile"
|
||||
print
|
||||
print "Options:"
|
||||
print
|
||||
print " -c <format> convert to format (default is given by extension)"
|
||||
print
|
||||
print " -g convert to greyscale"
|
||||
print " -p convert to palette image (using standard palette)"
|
||||
print " -r convert to rgb"
|
||||
print
|
||||
print " -o optimize output (trade speed for size)"
|
||||
print " -q <value> set compression quality (0-100, JPEG only)"
|
||||
print
|
||||
print " -f list supported file formats"
|
||||
print("PIL Convert 0.5/1998-12-30 -- convert image files")
|
||||
print("Usage: pilconvert [option] infile outfile")
|
||||
print()
|
||||
print("Options:")
|
||||
print()
|
||||
print(" -c <format> convert to format (default is given by extension)")
|
||||
print()
|
||||
print(" -g convert to greyscale")
|
||||
print(" -p convert to palette image (using standard palette)")
|
||||
print(" -r convert to rgb")
|
||||
print()
|
||||
print(" -o optimize output (trade speed for size)")
|
||||
print(" -q <value> set compression quality (0-100, JPEG only)")
|
||||
print()
|
||||
print(" -f list supported file formats")
|
||||
sys.exit(1)
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
|
@ -41,8 +43,8 @@ if len(sys.argv) == 1:
|
|||
|
||||
try:
|
||||
opt, argv = getopt.getopt(sys.argv[1:], "c:dfgopq:r")
|
||||
except getopt.error, v:
|
||||
print v
|
||||
except getopt.error as v:
|
||||
print(v)
|
||||
sys.exit(1)
|
||||
|
||||
format = None
|
||||
|
@ -54,14 +56,13 @@ for o, a in opt:
|
|||
|
||||
if o == "-f":
|
||||
Image.init()
|
||||
id = Image.ID[:]
|
||||
id.sort()
|
||||
print "Supported formats (* indicates output format):"
|
||||
id = sorted(Image.ID)
|
||||
print("Supported formats (* indicates output format):")
|
||||
for i in id:
|
||||
if Image.SAVE.has_key(i):
|
||||
print i+"*",
|
||||
if i in Image.SAVE:
|
||||
print(i+"*", end=' ')
|
||||
else:
|
||||
print i,
|
||||
print(i, end=' ')
|
||||
sys.exit(1)
|
||||
|
||||
elif o == "-c":
|
||||
|
@ -88,9 +89,9 @@ try:
|
|||
im.draft(convert, im.size)
|
||||
im = im.convert(convert)
|
||||
if format:
|
||||
apply(im.save, (argv[1], format), options)
|
||||
im.save(argv[1], format, **options)
|
||||
else:
|
||||
apply(im.save, (argv[1],), options)
|
||||
im.save(argv[1], **options)
|
||||
except:
|
||||
print "cannot convert image",
|
||||
print "(%s:%s)" % (sys.exc_type, sys.exc_value)
|
||||
print("cannot convert image", end=' ')
|
||||
print("(%s:%s)" % (sys.exc_info()[0], sys.exc_info()[1]))
|
||||
|
|
|
@ -48,8 +48,9 @@ of its upper-left-hand corner and displays the cropped portion.
|
|||
# 3. Add support for composing and decomposing multiple-image files.
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from PIL import Image
|
||||
import string
|
||||
|
||||
class PILDriver:
|
||||
|
||||
|
@ -206,7 +207,7 @@ class PILDriver:
|
|||
Process the top image with the given filter.
|
||||
"""
|
||||
import ImageFilter
|
||||
filter = eval("ImageFilter." + string.upper(self.do_pop()))
|
||||
filter = eval("ImageFilter." + self.do_pop().upper())
|
||||
image = self.do_pop()
|
||||
self.push(image.filter(filter))
|
||||
|
||||
|
@ -314,7 +315,7 @@ class PILDriver:
|
|||
|
||||
Transpose the top image.
|
||||
"""
|
||||
transpose = string.upper(self.do_pop())
|
||||
transpose = self.do_pop().upper()
|
||||
image = self.do_pop()
|
||||
self.push(image.transpose(transpose))
|
||||
|
||||
|
@ -482,9 +483,9 @@ class PILDriver:
|
|||
self.push(list[0])
|
||||
list = list[1:]
|
||||
if self.verbose:
|
||||
print "Stack: " + `self.stack`
|
||||
print("Stack: " + repr(self.stack))
|
||||
top = self.top()
|
||||
if type(top) != type(""):
|
||||
if not isinstance(top, str):
|
||||
continue;
|
||||
funcname = "do_" + top
|
||||
if not hasattr(self, funcname):
|
||||
|
@ -508,15 +509,15 @@ if __name__ == '__main__':
|
|||
if len(sys.argv[1:]) > 0:
|
||||
driver.execute(sys.argv[1:])
|
||||
else:
|
||||
print "PILDriver says hello."
|
||||
while 1:
|
||||
print("PILDriver says hello.")
|
||||
while True:
|
||||
try:
|
||||
line = raw_input('pildriver> ');
|
||||
except EOFError:
|
||||
print "\nPILDriver says goodbye."
|
||||
print("\nPILDriver says goodbye.")
|
||||
break
|
||||
driver.execute(string.split(line))
|
||||
print driver.stack
|
||||
driver.execute(line.split())
|
||||
print(driver.stack)
|
||||
|
||||
# The following sets edit modes for GNU EMACS
|
||||
# Local Variables:
|
||||
|
|
|
@ -17,25 +17,27 @@
|
|||
# 0.4 2003-09-30 fl Expand wildcards on Windows; robustness tweaks
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import site
|
||||
import getopt, glob, sys
|
||||
|
||||
from PIL import Image
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
print "PIL File 0.4/2003-09-30 -- identify image files"
|
||||
print "Usage: pilfile [option] files..."
|
||||
print "Options:"
|
||||
print " -f list supported file formats"
|
||||
print " -i show associated info and tile data"
|
||||
print " -v verify file headers"
|
||||
print " -q quiet, don't warn for unidentified/missing/broken files"
|
||||
print("PIL File 0.4/2003-09-30 -- identify image files")
|
||||
print("Usage: pilfile [option] files...")
|
||||
print("Options:")
|
||||
print(" -f list supported file formats")
|
||||
print(" -i show associated info and tile data")
|
||||
print(" -v verify file headers")
|
||||
print(" -q quiet, don't warn for unidentified/missing/broken files")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
opt, args = getopt.getopt(sys.argv[1:], "fqivD")
|
||||
except getopt.error, v:
|
||||
print v
|
||||
except getopt.error as v:
|
||||
print(v)
|
||||
sys.exit(1)
|
||||
|
||||
verbose = quiet = verify = 0
|
||||
|
@ -43,11 +45,10 @@ verbose = quiet = verify = 0
|
|||
for o, a in opt:
|
||||
if o == "-f":
|
||||
Image.init()
|
||||
id = Image.ID[:]
|
||||
id.sort()
|
||||
print "Supported formats:"
|
||||
id = sorted(Image.ID)
|
||||
print("Supported formats:")
|
||||
for i in id:
|
||||
print i,
|
||||
print(i, end=' ')
|
||||
sys.exit(1)
|
||||
elif o == "-i":
|
||||
verbose = 1
|
||||
|
@ -73,22 +74,22 @@ def globfix(files):
|
|||
for file in globfix(args):
|
||||
try:
|
||||
im = Image.open(file)
|
||||
print "%s:" % file, im.format, "%dx%d" % im.size, im.mode,
|
||||
print("%s:" % file, im.format, "%dx%d" % im.size, im.mode, end=' ')
|
||||
if verbose:
|
||||
print im.info, im.tile,
|
||||
print
|
||||
print(im.info, im.tile, end=' ')
|
||||
print()
|
||||
if verify:
|
||||
try:
|
||||
im.verify()
|
||||
except:
|
||||
if not quiet:
|
||||
print "failed to verify image",
|
||||
print "(%s:%s)" % (sys.exc_type, sys.exc_value)
|
||||
except IOError, v:
|
||||
print("failed to verify image", end=' ')
|
||||
print("(%s:%s)" % (sys.exc_info()[0], sys.exc_info()[1]))
|
||||
except IOError as v:
|
||||
if not quiet:
|
||||
print file, "failed:", v
|
||||
print(file, "failed:", v)
|
||||
except:
|
||||
import traceback
|
||||
if not quiet:
|
||||
print file, "failed:", "unexpected error"
|
||||
print(file, "failed:", "unexpected error")
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
# 2002-03-10 fl use "from PIL import"
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
VERSION = "0.4"
|
||||
|
||||
import site
|
||||
|
@ -19,12 +21,12 @@ from PIL import BdfFontFile
|
|||
from PIL import PcfFontFile
|
||||
|
||||
if len(sys.argv) <= 1:
|
||||
print "PILFONT", VERSION, "-- PIL font compiler."
|
||||
print
|
||||
print "Usage: pilfont fontfiles..."
|
||||
print
|
||||
print "Convert given font files to the PIL raster font format."
|
||||
print "This version of pilfont supports X BDF and PCF fonts."
|
||||
print("PILFONT", VERSION, "-- PIL font compiler.")
|
||||
print()
|
||||
print("Usage: pilfont fontfiles...")
|
||||
print()
|
||||
print("Convert given font files to the PIL raster font format.")
|
||||
print("This version of pilfont supports X BDF and PCF fonts.")
|
||||
sys.exit(1)
|
||||
|
||||
files = []
|
||||
|
@ -33,7 +35,7 @@ for f in sys.argv[1:]:
|
|||
|
||||
for f in files:
|
||||
|
||||
print f + "...",
|
||||
print(f + "...", end=' ')
|
||||
|
||||
try:
|
||||
|
||||
|
@ -48,7 +50,7 @@ for f in files:
|
|||
p.save(f)
|
||||
|
||||
except (SyntaxError, IOError):
|
||||
print "failed"
|
||||
print("failed")
|
||||
|
||||
else:
|
||||
print "OK"
|
||||
print("OK")
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
# 0.3 2003-05-06 fl Fixed a typo or two.
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
VERSION = "pilprint 0.3/2003-05-05"
|
||||
|
||||
from PIL import Image
|
||||
|
@ -29,18 +31,18 @@ def description(file, image):
|
|||
import getopt, os, sys
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
print "PIL Print 0.2a1/96-10-04 -- print image files"
|
||||
print "Usage: pilprint files..."
|
||||
print "Options:"
|
||||
print " -c colour printer (default is monochrome)"
|
||||
print " -p print via lpr (default is stdout)"
|
||||
print " -P <printer> same as -p but use given printer"
|
||||
print("PIL Print 0.2a1/96-10-04 -- print image files")
|
||||
print("Usage: pilprint files...")
|
||||
print("Options:")
|
||||
print(" -c colour printer (default is monochrome)")
|
||||
print(" -p print via lpr (default is stdout)")
|
||||
print(" -P <printer> same as -p but use given printer")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
opt, argv = getopt.getopt(sys.argv[1:], "cdpP:")
|
||||
except getopt.error, v:
|
||||
print v
|
||||
except getopt.error as v:
|
||||
print(v)
|
||||
sys.exit(1)
|
||||
|
||||
printer = None # print to stdout
|
||||
|
@ -50,7 +52,7 @@ for o, a in opt:
|
|||
if o == "-d":
|
||||
# debug: show available drivers
|
||||
Image.init()
|
||||
print Image.ID
|
||||
print(Image.ID)
|
||||
sys.exit(1)
|
||||
elif o == "-c":
|
||||
# colour printer
|
||||
|
@ -89,5 +91,5 @@ for file in argv:
|
|||
ps.end_document()
|
||||
|
||||
except:
|
||||
print "cannot print image",
|
||||
print "(%s:%s)" % (sys.exc_type, sys.exc_value)
|
||||
print("cannot print image", end=' ')
|
||||
print("(%s:%s)" % (sys.exc_info()[0], sys.exc_info()[1]))
|
||||
|
|
|
@ -3,7 +3,13 @@
|
|||
# $Id$
|
||||
#
|
||||
|
||||
from Tkinter import *
|
||||
from __future__ import print_function
|
||||
|
||||
try:
|
||||
from tkinter import *
|
||||
except ImportError:
|
||||
from Tkinter import *
|
||||
|
||||
from PIL import Image, ImageTk
|
||||
import sys
|
||||
|
||||
|
@ -36,7 +42,7 @@ class AppletDisplay:
|
|||
class UI(Label):
|
||||
|
||||
def __init__(self, master, im):
|
||||
if type(im) == type([]):
|
||||
if isinstance(im, list):
|
||||
# list of images
|
||||
self.im = im[1:]
|
||||
im = self.im[0]
|
||||
|
@ -65,7 +71,7 @@ class UI(Label):
|
|||
|
||||
def next(self):
|
||||
|
||||
if type(self.im) == type([]):
|
||||
if isinstance(self.im, list):
|
||||
|
||||
try:
|
||||
im = self.im[0]
|
||||
|
@ -98,7 +104,7 @@ class UI(Label):
|
|||
if __name__ == "__main__":
|
||||
|
||||
if not sys.argv[1:]:
|
||||
print "Syntax: python player.py imagefile(s)"
|
||||
print("Syntax: python player.py imagefile(s)")
|
||||
sys.exit(1)
|
||||
|
||||
filename = sys.argv[1]
|
||||
|
@ -108,7 +114,7 @@ if __name__ == "__main__":
|
|||
|
||||
if len(sys.argv) > 2:
|
||||
# list of images
|
||||
print "loading..."
|
||||
print("loading...")
|
||||
im = []
|
||||
for filename in sys.argv[1:]:
|
||||
im.append(Image.open(filename))
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
# as a dynamically updated overlay
|
||||
#
|
||||
|
||||
from Tkinter import *
|
||||
try:
|
||||
from tkinter import *
|
||||
except ImportError:
|
||||
from Tkinter import *
|
||||
|
||||
from PIL import Image, ImageTk
|
||||
import sys
|
||||
|
||||
|
|
|
@ -3,7 +3,13 @@
|
|||
# $Id$
|
||||
#
|
||||
|
||||
from Tkinter import *
|
||||
from __future__ import print_function
|
||||
|
||||
try:
|
||||
from tkinter import *
|
||||
except ImportError:
|
||||
from Tkinter import *
|
||||
|
||||
from PIL import Image, ImageTk
|
||||
|
||||
#
|
||||
|
@ -31,7 +37,7 @@ if __name__ == "__main__":
|
|||
import sys
|
||||
|
||||
if not sys.argv[1:]:
|
||||
print "Syntax: python viewer.py imagefile"
|
||||
print("Syntax: python viewer.py imagefile")
|
||||
sys.exit(1)
|
||||
|
||||
filename = sys.argv[1]
|
||||
|
|
4
Tests/README.txt
Normal file
4
Tests/README.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
Minimalistic PIL test framework.
|
||||
|
||||
Test scripts are named "test_xxx" and are supposed to output "ok".
|
||||
That's it.
|
20
Tests/bench_get.py
Normal file
20
Tests/bench_get.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
import sys
|
||||
sys.path.insert(0, ".")
|
||||
|
||||
import tester
|
||||
import timeit
|
||||
|
||||
def bench(mode):
|
||||
im = tester.lena(mode)
|
||||
get = im.im.getpixel
|
||||
xy = 50, 50 # position shouldn't really matter
|
||||
t0 = timeit.default_timer()
|
||||
for i in range(1000000):
|
||||
get(xy)
|
||||
print(mode, timeit.default_timer() - t0, "us")
|
||||
|
||||
bench("L")
|
||||
bench("I")
|
||||
bench("I;16")
|
||||
bench("F")
|
||||
bench("RGB")
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user