1package magic 2 3import "bytes" 4 5var ( 6 // Png matches a Portable Network Graphics file. 7 Png = prefix([]byte{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}) 8 // Jpg matches a Joint Photographic Experts Group file. 9 Jpg = prefix([]byte{0xFF, 0xD8, 0xFF}) 10 // Jp2 matches a JPEG 2000 Image file (ISO 15444-1). 11 Jp2 = jpeg2k([]byte{0x6a, 0x70, 0x32, 0x20}) 12 // Jpx matches a JPEG 2000 Image file (ISO 15444-2). 13 Jpx = jpeg2k([]byte{0x6a, 0x70, 0x78, 0x20}) 14 // Jpm matches a JPEG 2000 Image file (ISO 15444-6). 15 Jpm = jpeg2k([]byte{0x6a, 0x70, 0x6D, 0x20}) 16 // Gif matches a Graphics Interchange Format file. 17 Gif = prefix([]byte("GIF87a"), []byte("GIF89a")) 18 // Bmp matches a bitmap image file. 19 Bmp = prefix([]byte{0x42, 0x4D}) 20 // Ps matches a PostScript file. 21 Ps = prefix([]byte("%!PS-Adobe-")) 22 // Psd matches a Photoshop Document file. 23 Psd = prefix([]byte("8BPS")) 24 // Ico matches an ICO file. 25 Ico = prefix([]byte{0x00, 0x00, 0x01, 0x00}, []byte{0x00, 0x00, 0x02, 0x00}) 26 // Icns matches an ICNS (Apple Icon Image format) file. 27 Icns = prefix([]byte("icns")) 28 // Tiff matches a Tagged Image File Format file. 29 Tiff = prefix([]byte{0x49, 0x49, 0x2A, 0x00}, []byte{0x4D, 0x4D, 0x00, 0x2A}) 30 // Bpg matches a Better Portable Graphics file. 31 Bpg = prefix([]byte{0x42, 0x50, 0x47, 0xFB}) 32 // Xcf matches GIMP image data. 33 Xcf = prefix([]byte("gimp xcf")) 34 // Pat matches GIMP pattern data. 35 Pat = offset([]byte("GPAT"), 20) 36 // Gbr matches GIMP brush data. 37 Gbr = offset([]byte("GIMP"), 20) 38 // Hdr matches Radiance HDR image. 39 // https://web.archive.org/web/20060913152809/http://local.wasp.uwa.edu.au/~pbourke/dataformats/pic/ 40 Hdr = prefix([]byte("#?RADIANCE\n")) 41 // Xpm matches X PixMap image data. 42 Xpm = prefix([]byte{0x2F, 0x2A, 0x20, 0x58, 0x50, 0x4D, 0x20, 0x2A, 0x2F}) 43) 44 45func jpeg2k(sig []byte) Detector { 46 return func(raw []byte, _ uint32) bool { 47 if len(raw) < 24 { 48 return false 49 } 50 51 if !bytes.Equal(raw[4:8], []byte{0x6A, 0x50, 0x20, 0x20}) && 52 !bytes.Equal(raw[4:8], []byte{0x6A, 0x50, 0x32, 0x20}) { 53 return false 54 } 55 return bytes.Equal(raw[20:24], sig) 56 } 57} 58 59// Webp matches a WebP file. 60func Webp(raw []byte, _ uint32) bool { 61 return len(raw) > 12 && 62 bytes.Equal(raw[0:4], []byte("RIFF")) && 63 bytes.Equal(raw[8:12], []byte{0x57, 0x45, 0x42, 0x50}) 64} 65 66// Dwg matches a CAD drawing file. 67func Dwg(raw []byte, _ uint32) bool { 68 if len(raw) < 6 || raw[0] != 0x41 || raw[1] != 0x43 { 69 return false 70 } 71 dwgVersions := [][]byte{ 72 {0x31, 0x2E, 0x34, 0x30}, 73 {0x31, 0x2E, 0x35, 0x30}, 74 {0x32, 0x2E, 0x31, 0x30}, 75 {0x31, 0x30, 0x30, 0x32}, 76 {0x31, 0x30, 0x30, 0x33}, 77 {0x31, 0x30, 0x30, 0x34}, 78 {0x31, 0x30, 0x30, 0x36}, 79 {0x31, 0x30, 0x30, 0x39}, 80 {0x31, 0x30, 0x31, 0x32}, 81 {0x31, 0x30, 0x31, 0x34}, 82 {0x31, 0x30, 0x31, 0x35}, 83 {0x31, 0x30, 0x31, 0x38}, 84 {0x31, 0x30, 0x32, 0x31}, 85 {0x31, 0x30, 0x32, 0x34}, 86 {0x31, 0x30, 0x33, 0x32}, 87 } 88 89 for _, d := range dwgVersions { 90 if bytes.Equal(raw[2:6], d) { 91 return true 92 } 93 } 94 95 return false 96} 97 98// Jxl matches JPEG XL image file. 99func Jxl(raw []byte, _ uint32) bool { 100 return bytes.HasPrefix(raw, []byte{0xFF, 0x0A}) || 101 bytes.HasPrefix(raw, []byte("\x00\x00\x00\x0cJXL\x20\x0d\x0a\x87\x0a")) 102} 103