Merge pull request #35 from fluggo/master-1.7.8x

Add Python 3.2 support
This commit is contained in:
Alex Clark ☺ 2013-01-10 06:59:12 -08:00
commit b48257e259
230 changed files with 6784 additions and 2113 deletions

BIN
Images/lena.fli Normal file

Binary file not shown.

BIN
Images/lena.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
Images/lena.psd Normal file

Binary file not shown.

BIN
Images/lena.tar Normal file

Binary file not shown.

175
Images/lena.xpm Normal file
View 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@&@&#.@*&#.#@,@+@@+@@$@@@++++@@"};

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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"))

View File

@ -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):

View File

@ -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

View File

@ -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

View File

@ -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 = []

View File

@ -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")

View File

@ -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):

View File

@ -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

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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 = ""

View File

@ -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

View File

@ -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))

View File

@ -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):

View File

@ -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):

View File

@ -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):

View File

@ -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__':

View File

@ -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

View File

@ -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))])

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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 = {

View File

@ -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)

View File

@ -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):

View File

@ -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:

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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("'''))))")

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -14,7 +14,7 @@
# See the README file for information on usage and redistribution.
#
import Image
from . import Image
##
# Path wrapper.

View File

@ -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)

View File

@ -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:]))

View File

@ -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]

View File

@ -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()

View File

@ -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):

View File

@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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,

View File

@ -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.

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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):

View File

@ -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))])

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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))

View File

@ -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

View File

@ -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)

View File

@ -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):

View File

@ -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")

View File

@ -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))]

View File

@ -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

View File

@ -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"))

View File

@ -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

View File

@ -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")

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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
View 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)

View File

@ -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
}

View File

@ -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()

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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])

View File

@ -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

View File

@ -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]))

View File

@ -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:

View File

@ -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)

View File

@ -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")

View File

@ -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]))

View File

@ -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))

View File

@ -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

View File

@ -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
View 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
View 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