diff -r 5629481cd26d -r 4cdfb2ab87ac Doc/library/imghdr.rst --- a/Doc/library/imghdr.rst Tue Sep 30 21:16:27 2014 +0200 +++ b/Doc/library/imghdr.rst Thu Oct 02 23:15:34 2014 +0300 @@ -52,9 +52,30 @@ +------------+-----------------------------------+ | ``'exr'`` | OpenEXR Files | +------------+-----------------------------------+ +| ``'xpm'`` | X11 Pixel Maps Files | ++------------+-----------------------------------+ +| ``'eps'`` | Encapsulated Postscript Files | ++------------+-----------------------------------+ +| ``'ico'`` | ICO Files | ++------------+-----------------------------------+ +| ``'jp2'`` | JPEG2000 (JP2-codec) Files | ++------------+-----------------------------------+ +| ``'jpc'`` | JPEG2000 (JPC-codec) Files | ++------------+-----------------------------------+ +| ``'pcd'`` | Kodak PhotoCD Files | ++------------+-----------------------------------+ +| ``'tga'`` | Targa Files | ++------------+-----------------------------------+ +| ``'pcx'`` | PCExchange Files | ++------------+-----------------------------------+ +| ``'psd'`` | Photoshop Documents Files | ++------------+-----------------------------------+ +| ``'wmf'`` | Windows Metafiles Files | ++------------+-----------------------------------+ .. versionadded:: 3.5 - The *exr* format was added. + Was added *exr*, *xmp*, *eps*, *ico*, *jp2*, *jpc*, *pcd*, *tga*, *pcx*, + *psd*, *wmf* image formats. .. versionchanged:: 3.5 The *webp* type was added. diff -r 5629481cd26d -r 4cdfb2ab87ac Lib/imghdr.py --- a/Lib/imghdr.py Tue Sep 30 21:16:27 2014 +0200 +++ b/Lib/imghdr.py Thu Oct 02 23:15:34 2014 +0300 @@ -26,6 +26,22 @@ return None +#-----------------------------# +# Binary i/o support routines # +#-----------------------------# + +def _i8(c): + """Converts a 1-byte string to an integer.""" + return c if c.__class__ is int else c[0] + +def _i16_little_endian(c): + """Converts a 2-bytes string to an integer (little-endian).""" + return _i8(c[0]) | (_i8(c[1]) << 8) + +def _i16_big_endian(c): + """Converts a 2-bytes string to an integer (big-endian).""" + return (_i8(c[0]) << 8) | _i8(c[1]) + #---------------------------------# # Subroutines per image file type # #---------------------------------# @@ -34,7 +50,7 @@ def test_jpeg(h, f): """JPEG data in JFIF or Exif format""" - if h[6:10] in (b'JFIF', b'Exif'): + if len(h) > 1 and _i8(h[0]) == 255 and h[6:10] in (b'JFIF', b'Exif'): return 'jpeg' tests.append(test_jpeg) @@ -54,7 +70,7 @@ def test_tiff(h, f): """TIFF (can be in Motorola or Intel byte order)""" - if h[:2] in (b'MM', b'II'): + if h[:4] in [b"MM\000\052", b"II\052\000", b"II\xBC\000"]: return 'tiff' tests.append(test_tiff) @@ -69,7 +85,7 @@ def test_pbm(h, f): """PBM (portable bitmap)""" if len(h) >= 3 and \ - h[0] == ord(b'P') and h[1] in b'14' and h[2] in b' \t\n\r': + h[0] == _i8(b'P') and h[1] in b'14' and h[2] in b' \t\n\r': return 'pbm' tests.append(test_pbm) @@ -77,7 +93,7 @@ def test_pgm(h, f): """PGM (portable graymap)""" if len(h) >= 3 and \ - h[0] == ord(b'P') and h[1] in b'25' and h[2] in b' \t\n\r': + h[0] == _i8(b'P') and h[1] in b'25' and h[2] in b' \t\n\r': return 'pgm' tests.append(test_pgm) @@ -85,7 +101,7 @@ def test_ppm(h, f): """PPM (portable pixmap)""" if len(h) >= 3 and \ - h[0] == ord(b'P') and h[1] in b'36' and h[2] in b' \t\n\r': + h[0] == _i8(b'P') and h[1] in b'36' and h[2] in b' \t\n\r': return 'ppm' tests.append(test_ppm) @@ -105,23 +121,97 @@ tests.append(test_xbm) def test_bmp(h, f): + """BMP files""" if h.startswith(b'BM'): return 'bmp' tests.append(test_bmp) def test_webp(h, f): - if h.startswith(b'RIFF') and h[8:12] == b'WEBP': + """WebP files""" + if h.startswith(b'RIFF') and h[8:12] == b'WEBP' and h[12:16] in (b"VP8 ", b"VP8X", b"VP8L"): return 'webp' tests.append(test_webp) def test_exr(h, f): + """OpenEXR files""" if h.startswith(b'\x76\x2f\x31\x01'): return 'exr' tests.append(test_exr) +def test_xpm(h, f): + """X11 Pixel Maps Files""" + if h[:9] == b"/* XPM */": + return 'xpm' + +tests.append(test_xpm) + +def test_eps(h, f): + """Encapsulated Postscript files""" + if h[:4] == b"%!PS": + return 'eps' + +tests.append(test_eps) + +def test_ico(h, f): + """ICO files""" + if h[:4] == b"\0\0\1\0": + return 'ico' + +tests.append(test_ico) + +def test_jpeg2k_jp2(h, f): + """JPEG2000 files (JP2-codec)""" + if h[:12] == b'\x00\x00\x00\x0cjP \x0d\x0a\x87\x0a': + return 'jp2' + +tests.append(test_jpeg2k_jp2) + +def test_jpeg2k_jpc(h, f): + """JPEG2000 files (JPC-codec)""" + if h[:4] == b'\xff\x4f\xff\x51': + return 'jpc' + +tests.append(test_jpeg2k_jpc) + +def test_pcd(h, f): + """Kodak PhotoCD files""" + if h[:4] == b"PCD_": + return 'pcd' + +tests.append(test_pcd) + +def test_tga(h, f): + """Targa files""" + if len(h) >= 18 and h[1] in (0, 1) and h[16] in (1, 8, 16, 24, 32) \ + and _i16_little_endian(h[12:18]) > 0 and _i16_little_endian(h[14:18]) > 0: + return 'tga' + +tests.append(test_tga) + +def test_pcx(h, f): + """PCExchange files""" + if len(h) >= 2 and _i8(h[0]) == 10 and _i8(h[1]) in (0, 2, 3, 5): + return 'pcx' + +tests.append(test_pcx) + +def test_psd(h, f): + """Photoshop Document files""" + if h[:4] == b"8BPS" and _i16_big_endian(h[4:22]) == 1: + return 'psd' + +tests.append(test_psd) + +def test_wmf(h, f): + """Windows Metafiles Files""" + if h[:6] == b"\xd7\xcd\xc6\x9a\x00\x00" and h[22:26] == b"\x01\x00\t\x00": + return 'wmf' + +tests.append(test_wmf) + #--------------------# # Small test program # #--------------------# diff -r 5629481cd26d -r 4cdfb2ab87ac Lib/test/imghdrdata/python.eps --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/test/imghdrdata/python.eps Thu Oct 02 23:15:34 2014 +0300 @@ -0,0 +1,299 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: (ImageMagick) +%%Title: (/srv/www/vhosts/online-convert.com/save/queued/e/1/7/e179338825c0a279286e6de69f1991e8/intermediate1/o_70277d4b60f673f3.eps) +%%CreationDate: (2014-10-01T21:52:48+02:00) +%%BoundingBox: -0 -0 16 16 +%%HiResBoundingBox: 0 0 16 16 +%%DocumentData: Clean7Bit +%%LanguageLevel: 1 +%%Pages: 1 +%%EndComments + +%%BeginDefaults +%%EndDefaults + +%%BeginProlog +% +% Display a color image. The image is displayed in color on +% Postscript viewers or printers that support color, otherwise +% it is displayed as grayscale. +% +/DirectClassPacket +{ + % + % Get a DirectClass packet. + % + % Parameters: + % red. + % green. + % blue. + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/DirectClassImage +{ + % + % Display a DirectClass image. + % + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { DirectClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayDirectClassPacket } image + } ifelse +} bind def + +/GrayDirectClassPacket +{ + % + % Get a DirectClass packet; convert to grayscale. + % + % Parameters: + % red + % green + % blue + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/GrayPseudoClassPacket +{ + % + % Get a PseudoClass packet; convert to grayscale. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassPacket +{ + % + % Get a PseudoClass packet. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassImage +{ + % + % Display a PseudoClass image. + % + % Parameters: + % class: 0-PseudoClass or 1-Grayscale. + % + currentfile buffer readline pop + token pop /class exch def pop + class 0 gt + { + currentfile buffer readline pop + token pop /depth exch def pop + /grays columns 8 add depth sub depth mul 8 idiv string def + columns rows depth + [ + columns 0 0 + rows neg 0 rows + ] + { currentfile grays readhexstring pop } image + } + { + % + % Parameters: + % colors: number of colors in the colormap. + % colormap: red, green, blue color packets. + % + currentfile buffer readline pop + token pop /colors exch def pop + /colors colors 3 mul def + /colormap colors string def + currentfile colormap readhexstring pop pop + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { PseudoClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayPseudoClassPacket } image + } ifelse + } ifelse +} bind def + +/DisplayImage +{ + % + % Display a DirectClass or PseudoClass image. + % + % Parameters: + % x & y translation. + % x & y scale. + % label pointsize. + % image label. + % image columns & rows. + % class: 0-DirectClass or 1-PseudoClass. + % compression: 0-none or 1-RunlengthEncoded. + % hex color packets. + % + gsave + /buffer 512 string def + /byte 1 string def + /color_packet 3 string def + /pixels 768 string def + + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + x y translate + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + currentfile buffer readline pop + token pop /pointsize exch def pop + /Times-Roman findfont pointsize scalefont setfont + x y scale + currentfile buffer readline pop + token pop /columns exch def + token pop /rows exch def pop + currentfile buffer readline pop + token pop /class exch def pop + currentfile buffer readline pop + token pop /compression exch def pop + class 0 gt { PseudoClassImage } { DirectClassImage } ifelse + grestore +} bind def +%%EndProlog +%%Page: 1 1 +%%PageBoundingBox: 0 0 16 16 +userdict begin +DisplayImage +0 0 +16 16 +12 +16 16 +0 +0 +0002080000050100040004106582A05884AB4F7FAD497BAC4976AF436B9C41637E000613000106 +03000000020000020000050D00030B0001090003126586A5D7FFFF5083AE4074A33F6DA1436C9A +4D6C8900041300010501000000010001060000030B00040E00091900071E5782A24B7FA4427A9F +437AA13B6B99456B98405D7F000219000309030804000200000501000B1F6A8AA15F84A15782A5 +4D7FA4427A9F336F942B668E396E9A3C66904A62860007130103000703000907000502005590B8 +5288B45684B6507EB2447AA83A77A33675A131709C2A67933E6E9449617D000200EFDE8EF6DE7E +E5D1941100004A8DC24D8CC14F84BA4A7DB24176A8427BA838729A346B92386E944169824D5D5C +0F0900FBDE69FBD856E9CE77180000578BC54B83B64882A8437BA04070A1446F9C3E6A8741677E +43627E45585C080600DDCB69F6D44CFCD64FF0D3751901004E80B54E82B1427B9947799047677E +1C323F000700000A00000700060800D2C463F7DB56FFDB44F3CE41EACD671C03004983AB427A9F +487999456771000600E3DEA6F1E696F0E482F1E67AEEE065F8DD52FCD941F8D231F2CE3AECD062 +1B0400467F9D4B7E9D49708D223634DFDE9EFBE882FFE46CFFE35AF8DD48FDDF43F9D235FFD737 +FAD12BF4D03ED6BE541A0800497894466E88506880000400F4EC97FFEC6FFFDF5AFFDA4FFFD847 +FFD743FFD239FBC628FBCB29F3CD44AE99460F030000061B00091B000212090900F5E784F7DD52 +FFDD4EF0C133EFC034EEBF35EDBC33E9BB34DFB837B89B3512010014060000000B000209000306 +070300EFDD71FFE755FFDC46FDD542F7D148F1CF51E8C8591E05001103001105001402000E0000 +070000040000040301080200F6E27FF9DC5AF6D14DF7D452EFD155FFFF96D9C56E0E0400040400 +0001000700020D0006060200030200010000070100DCCB85E4CD6FEFD075EBCC6FE7CE6AD5C067 +AA9B5A0904000003000107070000040100050001000001000100020701001405001704001C0000 +1D02001C02001906000F0200060200000300000304000105000106 + +end +%%PageTrailer +%%Trailer +%%EOF diff -r 5629481cd26d -r 4cdfb2ab87ac Lib/test/imghdrdata/python.ico Binary file Lib/test/imghdrdata/python.ico has changed diff -r 5629481cd26d -r 4cdfb2ab87ac Lib/test/imghdrdata/python.jp2 Binary file Lib/test/imghdrdata/python.jp2 has changed diff -r 5629481cd26d -r 4cdfb2ab87ac Lib/test/imghdrdata/python.jpc Binary file Lib/test/imghdrdata/python.jpc has changed diff -r 5629481cd26d -r 4cdfb2ab87ac Lib/test/imghdrdata/python.pcx Binary file Lib/test/imghdrdata/python.pcx has changed diff -r 5629481cd26d -r 4cdfb2ab87ac Lib/test/imghdrdata/python.psd Binary file Lib/test/imghdrdata/python.psd has changed diff -r 5629481cd26d -r 4cdfb2ab87ac Lib/test/imghdrdata/python.tga Binary file Lib/test/imghdrdata/python.tga has changed diff -r 5629481cd26d -r 4cdfb2ab87ac Lib/test/imghdrdata/python.wmf Binary file Lib/test/imghdrdata/python.wmf has changed diff -r 5629481cd26d -r 4cdfb2ab87ac Lib/test/imghdrdata/python.xpm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/test/imghdrdata/python.xpm Thu Oct 02 23:15:34 2014 +0300 @@ -0,0 +1,124 @@ +/* XPM */ +static char *python[] = { +/* columns rows colors chars-per-pixel */ +"16 16 102 2", +" c #EBBB18", +". c #EBBE21", +"X c #F3C11A", +"o c #FAC719", +"O c #FDCB1B", +"+ c #FFCC1C", +"@ c #EBC22A", +"# c #FFCF23", +"$ c #FFCF24", +"% c #FFD025", +"& c #FFD026", +"* c #FFD32D", +"= c #FDD22F", +"- c #FFD32E", +"; c #FFD32F", +": c #EBC534", +"> c #E8C73D", +", c #FFD330", +"< c #FFD430", +"1 c #FDD536", +"2 c #FFD637", +"3 c #FAD339", +"4 c #FFD738", +"5 c #FFD739", +"6 c #FFD73A", +"7 c #F9D53E", +"8 c #FFD83A", +"9 c #ECCE45", +"0 c #FDD941", +"q c #FFDA41", +"w c #FFDA42", +"e c #FFDB42", +"r c #FFDB43", +"t c #FFDB44", +"y c #FDDD4A", +"u c #FFDE4B", +"i c #FFDF4D", +"p c #FDDE4E", +"a c #FFDF4E", +"s c #FFE255", +"d c #FFE357", +"f c #FFE358", +"g c #FFE661", +"h c #FFE761", +"j c #FFE762", +"k c #F2E16E", +"l c #F5E36F", +"z c #FDE96A", +"x c #FFEB6C", +"c c #326087", +"v c #366690", +"b c #366791", +"n c #356892", +"m c #366993", +"M c #366994", +"N c #376896", +"B c #376A96", +"V c #396C96", +"C c #386C97", +"Z c #396D99", +"A c #3A6F9B", +"S c #3A709C", +"D c #3B709C", +"F c #3B709D", +"G c #3C719E", +"H c #3D73A0", +"J c #3D73A2", +"K c #3D74A1", +"L c #3E74A2", +"P c #3E75A3", +"I c #3F76A5", +"U c #4078A6", +"Y c #4078A7", +"T c #4179A8", +"R c #427BAA", +"E c #437CAB", +"W c #437DAD", +"Q c #437DAE", +"! c #447DAD", +"~ c #447EAD", +"^ c #457FAF", +"/ c #4680B0", +"( c #4680B1", +") c #4681B2", +"_ c #4781B2", +"` c #4883B4", +"' c #4884B5", +"] c #4885B6", +"[ c #4985B7", +"{ c #4A87B9", +"} c #4A86BA", +"| c #4B88BB", +" . c #4C89BC", +".. c #4C8ABC", +"X. c #4D8BBE", +"o. c #4C8ABF", +"O. c #4E8DC0", +"+. c #4F8DC1", +"@. c #508FC3", +"#. c #5291C6", +"$. c #FFFFFF", +"%. c None", +/* pixels */ +"%.%.%.%.+.} ( W I G N %.%.%.%.%.", +"%.%.%.%...$.( R L S B %.%.%.%.%.", +"%.%.%.%.] ( R L D B m %.%.%.%.%.", +"%.%.o.] W L V v V B B %.%.%.%.%.", +"#.+. .` ^ U G A m B B %.s u 7 %.", +"@.o._ ^ R G A m m m c %.u q 1 %.", +"o.] _ R L G B B b c %.9 q 1 * %.", +"] _ E U m %.%.%.%.%.%.q 5 * # %.", +"( W U b %.k z j s a q 8 * $ O %.", +"W R L %.l x j f a t 5 , $ + X %.", +"%.J D %.x j f a q 8 * $ + + %.%.", +"%.%.%.%.j f a > : @ . %.%.%.", +"%.%.%.%.f a t 5 , % + %.%.%.%.%.", +"%.%.%.%.a t 5 < % $.O %.%.%.%.%.", +"%.%.%.%.%.3 , % + o %.%.%.%.%.%.", +"%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%." +}; diff -r 5629481cd26d -r 4cdfb2ab87ac Lib/test/test_imghdr.py --- a/Lib/test/test_imghdr.py Tue Sep 30 21:16:27 2014 +0200 +++ b/Lib/test/test_imghdr.py Thu Oct 02 23:15:34 2014 +0300 @@ -19,6 +19,15 @@ ('python.xbm', 'xbm'), ('python.webp', 'webp'), ('python.exr', 'exr'), + ('python.xpm', 'xpm'), + ('python.eps', 'eps'), + ('python.ico', 'ico'), + ('python.jp2', 'jp2'), + ('python.jpc', 'jpc'), + ('python.tga', 'tga'), + ('python.pcx', 'pcx'), + ('python.psd', 'psd'), + ('python.wmf', 'wmf'), ) class UnseekableIO(io.FileIO):