Browse Source

demux: image: fix JFIF detection

A JFIF does not necessarily has an ICC Profile, and especially
not usually directly following the SOI, as the spec requires SOI
followed by the APP0 JFIF marker. So while this new detection logic
fixes out-of-spec files that have a (small) ICC profile before the
APP0 JFIF, it breaks most other properly structured ones.

This makes the APP0 ICC profile optional and continues looking for the
APP0 JFIF regardless.

Regression from 5ffd36ffa2
work/string-cache
Marvin Scholz 8 months ago
committed by Steve Lhomme
parent
commit
70eb2735e7
  1. 45
      modules/demux/image.c

45
modules/demux/image.c

@ -415,26 +415,32 @@ static bool IsJfif(stream_t *s)
size_t size = (size_t) peek;
size_t position = 0;
if (FindJpegMarker(&position, header, size) != 0xd8)
return false;
if (FindJpegMarker(&position, header, size) == 0xe2) // ICC Profile
{
size_t icc_size = GetWBE(&header[position]);
position += 2;
if (position + 12 > size)
return false;
if (memcmp(&header[position], "ICC_PROFILE\0", 12))
return false;
position += icc_size - 2;
if (FindJpegMarker(&position, header, size) != 0xd8) // SOI
return false;
while (1) {
uint8_t marker = FindJpegMarker(&position, header, size);
switch (marker) {
case 0xe2: { // ICC Profile
size_t icc_size = GetWBE(&header[position]);
position += 2;
if (position + 12 > size)
return false;
if (memcmp(&header[position], "ICC_PROFILE\0", 12))
return false;
position += icc_size - 2;
break;
}
case 0xe0: { // APP0
position += 2; /* Skip size */
if (position + 5 > size)
return false;
return (memcmp(&header[position], "JFIF\0", 5) == 0);
}
default:
return false;
}
}
if (FindJpegMarker(&position, header, size) != 0xe0)
return false;
position += 2; /* Skip size */
if (position + 5 > size)
return false;
if (memcmp(&header[position], "JFIF\0", 5))
return false;
return true;
}
static bool IsWebP(stream_t *s)
@ -822,4 +828,3 @@ static void Close(vlc_object_t *object)
block_Release(sys->data);
free(sys);
}

Loading…
Cancel
Save