我有一些不同的JPEG图像,我一直在测试。据我所见,第0个和第一个字节始终是0xFF
和0xD8
。
第二个和第三个通常是0xFF
和0xE0
(APP0),表示JFIF段或JFIF扩展段或0xFF
和0xE1
(APP1)表示EXIF细分。
我的问题:这种情况总是如此吗?第2和第3个字节总是APP0还是APP1?
答案 0 :(得分:9)
没有。例如有几个没有这些标记或其他APP标记创建JPEG的相机。您唯一可以依赖的是SOI序列,FF D8
,甚至EOI都不是由所有摄像机生成的。另请注意,存在嵌入JPEG的JPEG - 您可以在图像中嵌套SOI / EOI。
如果你需要在原始相机图像中处理嵌入的JPEG数据,那么几个模型会产生类似JPEG的数据,这些数据只能通过jpeg规范稍微松散来解析 - 特别是与转义的FF
字节有关在数据中。然后你有相机产生专有数据,乍一看看起来像jpeg数据(例如索尼的一些“加密”原始格式)
答案 1 :(得分:2)
不,它肯定不一定是这样。阅读Wikipedia。
据我所知,APPn段只是应用程序将任意数据嵌入图像文件的方法。显然,应用程序通常会利用这一点并将0xFF 0xEO
或0xFF 0xE1
字节写入标题中,但对于不的应用程序来说,完全可行并且继续与图像数据。前两个字节(0xFF和0xD8)是必需的,因为它们是SOI(图像起始)标记。
答案 2 :(得分:2)
这里的事情很复杂。由于我目前正在编写一个javascript文件标识符,因此我将尝试使用我的javascript对象来回答JPEG。 特别是因为这个问题有一个“javascript”标签。
已经给出了基本答案(已接受的答案),但这更详细地说明了如何检查不同的App标记(使用后备)。
到目前为止,JFIF,EXIF,Adobe,佳能和三星都有特殊的APP0(但我们不知道未来)。所以js对象的逻辑是:
如果其中一个SPECS [x] .regex匹配,则获胜(第一个获胜)。但如果没有匹配,父对象(仅FFd8)将获胜。
SPECS对象提供根据PRONOM标识符 - 您可以像这样查看
'http://apps.nationalarchives.gov.uk/pronom/fmt/'。concat(PUID)[官方] 'http://apps.nationalarchives.gov.uk/pronom/x-fmt/'。concat(xPUID)[experimental]
_FFD8: {
SPECS: [
{
PUID: 112,
regex: /^FFD8FFE8(.{2})53504946460001/,
desc: 'jpeg: Still Picture Interchange Format file (SPIF)',
regexCapture: [
{ key: 'recordedSignature' },
{ key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } }
],
valueCapture: {
version: '1.00'
}
},
{
PUID: 44,
regex: /^FFD8FFE0(.{2})4A464946000102/,
desc: 'jpeg: JPEG File Interchange Format file (JFIF), v. 1.02',
regexCapture: [
{ key: 'recordedSignature' },
{ key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } }
],
valueCapture: {
version: '1.02',
}
},
{
PUID: 43,
regex: /^FFD8FFE0(.{2})4A464946000101/,
desc: 'jpeg: JPEG File Interchange Format file (JFIF), v. 1.01',
regexCapture: [
{ key: 'recordedSignature' },
{ key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } }
],
valueCapture: {
version: '1.01',
}
},
{
PUID: 42,
regex: /^FFD8FFE0(.{2})4A464946000100/,
desc: 'jpeg: JPEG File Interchange Format file (JFIF), v. 1.00',
regexCapture: [
{ key: 'recordedSignature' },
{ key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } }
],
valueCapture: {
version: '1.00',
}
},
{
PUID: 41,
xPUID: 398,
regex: /^FFD8FFE1(.{2})45786966000049492A00(.+)009007000400000030323030/,
desc: 'jpeg: JPG Image File, using Exchangeable Image File Format (Exif), little endian, v. 2.0',
regexCapture: [
{ key: 'recordedSignature' },
{ key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } }
],
valueCapture: {
endian: 'little',
version: '2.0',
}
},
{
PUID: 41,
xPUID: 398,
regex: /^FFD8FFE1(.{2})4578696600004D4D002A(.+)900000070000000430323030/,
desc: 'jpeg: JPG Image File, using Exchangeable Image File Format (Exif), big endian, v. 2.0',
regexCapture: [
{ key: 'recordedSignature' },
{ key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } }
],
valueCapture: {
endian: 'big',
version: '2.0',
}
},
{
PUID: 41,
xPUID: 390,
regex: /^FFD8FFE1(.{2})45786966000049492A00(.+)009007000400000030323130/,
desc: 'jpeg: JPG Image File, using Exchangeable Image File Format (Exif), little endian, v. 2.1',
regexCapture: [
{ key: 'recordedSignature' },
{ key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } }
],
valueCapture: {
endian: 'little',
version: '2.1',
}
},
{
PUID: 41,
xPUID: 390,
regex: /^FFD8FFE1(.{2})4578696600004D4D002A(.+)900000070000000430323130/,
desc: 'jpeg: JPG Image File, using Exchangeable Image File Format (Exif), big endian, v. 2.1',
regexCapture: [
{ key: 'recordedSignature' },
{ key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } }
],
valueCapture: {
endian: 'big',
version: '2.1',
}
},
{
PUID: 41,
xPUID: 391,
regex: /^FFD8FFE1(.{2})45786966000049492A00(.+)009007000400000030323230/,
desc: 'jpeg: JPG Image File, using Exchangeable Image File Format (Exif), little endian, v. 2.2',
regexCapture: [
{ key: 'recordedSignature' },
{ key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } }
],
valueCapture: {
endian: 'little',
version: '2.2',
}
},
{
PUID: 41,
xPUID: 391,
regex: /^FFD8FFE1(.{2})4578696600004D4D002A(.+)900000070000000430323230/,
desc: 'jpeg: JPG Image File, using Exchangeable Image File Format (Exif), big endian, v. 2.2',
regexCapture: [
{ key: 'recordedSignature' },
{ key: 'segmentLength', fn: function(h){ return { value:parseInt(h, 16), _val:h.toString() }; } }
],
valueCapture: {
endian: 'big',
version: '2.2',
}
},
// specific JPEG (all begin with FFD8FF, map them to PUID 41)
{
PUID: 41,
regex: /^FFD8FFED/,
desc: 'jpeg: JPG Image File, Adobe JPEG, Photoshop CMYK buffer'
},
{
PUID: 41,
regex: /^FFD8FFE2/,
desc: 'jpeg: JPG Image File, Canon JPEG, Canon EOS-1D'
},
{
PUID: 41,
regex: /^FFD8FFE3/,
desc: 'jpeg: JPG Image File, Samsung JPEG, e.g. Samsung D500'
},
{
PUID: 41,
regex: /^FFD8FFDB/,
desc: 'jpeg: JPG Image File, Samsung JPEG, e.g. Samsung D807'
}
],
ext: ['JPG', 'JPE', 'JPEG', 'SPF', 'SPIFF'],
signature: [ 255, 216 ],
desc: 'jpeg: JPEG File Interchange Format file, App0 marker not known',
mime: 'image/jpeg',
specifications: [
{ text:'Specification for the JFIF file format', href:'http://www.w3.org/Graphics/JPEG/jfif3.pdf', type:'W3', format:'pdf' },
{ text:'The JPEG compression specification', href:'http://www.w3.org/Graphics/JPEG/itu-t81.pdf', type:'W3', format:'pdf' },
{ text:'Exchangeable image file format for digital still cameras', href:'http://home.jeita.or.jp/tsc/std-pdf/CP3451C.pdf', type:'vendor', format:'pdf' }
],
references: [
{ text:'JPEG JFIF W3 Info', href:'http://www.w3.org/Graphics/JPEG/', type:'W3', format:'html' },
{ text:'JPEG.org', href:'http://www.jpeg.org/', type:'info', format:'html' },
{ text:'JPEG Exif App markers', href:'http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/JPEG.html', type:'info', format:'html'}
]
}
答案 3 :(得分:1)
答案 4 :(得分:1)
通常是的,但是我对JPEG的理解是任何段类型都可以跟随标题。
答案 5 :(得分:1)
没有。有一些程序可以删除一些标记。 ImageOptim就是这样一个程序。你只需要一些标记。该程序还将优化霍夫曼表
答案 6 :(得分:0)
对于JFIF文件,在FFD8之后,JFIF头应立即跟随。 JFIF标头包含在APP0标记内。该规范没有提及任何关于填充的内容。
如果没有JFIF标题,我们只能猜测使用的颜色格式。
答案 7 :(得分:0)
理论上,是的。根据{{3}} (pdf),其APP0部分应该位于文件的第一位。 JFIF spec (pdf)对其APP1部分要求相同。
但你不应指望APPn部分的顺序(甚至存在);那里有疯狂的JPEG作家。从SOI开始,阅读各部分。