©
. Document créé le 12 juillet 2006 , mis à jour le 9 octobre 2011.Qu'importe le flacon, pourvu qu'on ait l'ivresse. Alfred de Musset
Accueil du site > PHP Lib > PHP Lib JPEG
Fonctions PHP JPEG : La libraire des fonctions JPEG permet l’édition de fichiers JPEG/JFIF. Les fonctions présentées ici sont expérimentales, mais devrait permettrent au novice de mieux comprendre la structure du format de fichier image JPEG/JFIF.
Le format de fichier JPEG est basé sur un assemblage d’éléments, de segments, enveloppés de marqueurs.
Structure d’un fichier JPEG JFIF :
Nom | Marqueur | Legend | Description |
---|---|---|---|
M_SOI | 0xff 0xd8 | Start of image | Début du fichier (magic number) |
M_APP0 | 0xff 0xe0 | Application marker, used for JFIF | Segment Application. |
... | Divers segments suivent... | ||
... | ... | ||
M_SOS | 0xff 0xda | Start of scan | L’image commence ici. |
M_EOI | 0xff 0xd9 | End of image | L’image prend fin ici. Le fichier aussi. |
Un fichier JPEG correctement constitué commence donc par la séquence "0xff 0xd8", contient en général le segment APP0 (qui contient parfois la vignette - thumbnail - de l’image, mais ce n’est guère plus pratiqué), suivi d’un ou plusieurs segments de tables Huffman et autres extensions, et prend fin avec le segment de l’image compressée.
Liste des segments disponibles :
Marqueur | Valeur | Legend |
---|---|---|
0xc0 | M_SOF0 | Baseline DCT |
0xc1 | M_SOF1 | Extended sequential DCT |
0xc2 | M_SOF2 | Progressive DCT |
0xc3 | M_SOF3 | Lossless (sequential) |
0xc5 | M_SOF5 | Differential sequential DCT |
0xc6 | M_SOF6 | Differential progressive DCT |
0xc7 | M_SOF7 | Differential lossless |
0xc8 | M_JPG | JPEG extensions |
0xc9 | M_SOF9 | Extended sequential DCT |
0xca | M_SOF10 | Progressive DCT |
0xcb | M_SOF11 | Lossless (sequential) |
0xcd | M_SOF13 | Differential sequential DCT |
0xce | M_SOF14 | Differential progressive DCT |
0xcf | M_SOF15 | Differential lossless |
0xc4 | M_DHT | Define Huffman tables |
0xcc | M_DAC | Define arithmetic conditioning table |
0xd0 | M_RST0 | Restart |
0xd1 | M_RST1 | Restart |
0xd2 | M_RST2 | Restart |
0xd3 | M_RST3 | Restart |
0xd4 | M_RST4 | Restart |
0xd5 | M_RST5 | Restart |
0xd6 | M_RST6 | Restart |
0xd7 | M_RST7 | Restart |
0xd8 | M_SOI | Start of image |
0xd9 | M_EOI | End Of Image |
0xda | M_SOS | Start Of Scan |
0xdb | M_DQT | Define quantization tables |
0xdc | M_DNL | Define number of lines |
0xdd | M_DRI | Define restart interval |
0xde | M_DHP | Define hierarchical progression |
0xdf | M_EXP | Expand reference image(s) |
0xe0 | M_APP0 | Application marker, used for JFIF |
0xe1 | M_APP1 | Application marker |
0xe2 | M_APP2 | Application marker |
0xe3 | M_APP3 | Application marker |
0xe4 | M_APP4 | Application marker |
0xe5 | M_APP5 | Application marker |
0xe6 | M_APP6 | Application marker |
0xe7 | M_APP7 | Application marker |
0xe8 | M_APP8 | Application marker |
0xe9 | M_APP9 | Application marker |
0xea | M_APP10 | Application marker |
0xeb | M_APP11 | Application marker |
0xec | M_APP12 | Application marker |
0xed | M_APP13 | Application marker |
0xee | M_APP14 | Application marker, used by Adobe |
0xef | M_APP15 | Application marker |
0xf0 | M_JPG0 | Reserved for JPEG extensions |
0xfd | M_JPG13 | Reserved for JPEG extensions |
0xfe | M_COM | Comment |
0x01 | M_TEM | Temporary use |
0x100 | M_ERROR | Dummy marker, internal use only |
0xff | M_SMS | Start Marker Segment |
Normalement, le fichier est terminé par un EOI (End of Image) qui est à la fois la fin du segment image (votre image compressée) et la fin du fichier.
Il arrive parfois que le fichier soit abimé. jpeginfo vous indique "Premature end of JPEG file", et la commande PHP imagecreatefromjpeg refuse de charger le fichier (PHP <5.1.3+). Si ce fichier ne s’affiche pas correctement sur votre navigateur (Firefox, etc.), c’est qu’il est tronqué. Si par contre l’image est bonne, c’est qu’il manque la marqueur de fin de fichier (EOI) et que parfois, la fin du segment image (de SOS à EOI) est erronée.
La commande kzo_jpeg_struct_get () disponible ici est une version beta de ce qui pourra peut-être vous servir à mieux comprendre la structure d’une image JPEG. Cette fonction vous renvoie un tableau multi-dimensionné contenant l’ensemble des informations rencontrées dans ce fichier JPEG (structure et ses segments).
Voici en exemple (résultat et image), ce que donne kzo_jpeg_struct_get () :
Segment #0
#0 APP: M_APP0 [0xe0] (Application marker, used for JFIF)
#0 Length: 16
#0 Identifier: JFIF
#0 Version: 1.2
#0 Units: 0
#0 Xdensity: 100
#0 Ydensity: 100
#0 XThumbnail: 0
#0 YThumbnail: 0
#0 data: <... 0 bytes length ...>
Segment #1
#1 APP: M_APP12 [0xec] (Application marker)
#1 Length: 17
#1 Data: <... 14 bytes length ...>
Segment #2
#2 APP: M_APP14 [0xee] (Application marker, used by Adobe)
#2 Length: 38
#2 Data: <... 35 bytes length ...>
Segment #3
#3 APP: M_DQT [0xdb] (Define quantization tables)
#3 Length: 132
#3 Table: <... 129 bytes length ...>
Segment #4
#4 APP: M_SOF2 [0xc2] (Progressive DCT)
#4 Length: 17
#4 Data: <... 14 bytes length ...>
Segment #5
#5 APP: M_DHT [0xc4] (Define Huffman tables)
#5 Length: 213
#5 Data: <... 210 bytes length ...>
Segment #6
#6 APP: M_SOS [0xda] (Start Of Scan)
#6 scan: <... 6089 bytes length ...>
Segment #7
#7 APP: M_EOI [0xd9] (End Of Image)
Voici un code PHP en exemple à compléter pour utiliser kzo_jpeg_struct_get () :
<?php
echo("<pre>");
$filename = "votre-image-jpeg.jpg";
echo("Filename: $filename\n");
echo("Filesize: ".filesize($filename)." bytes\n");
$image_file = file_get_contents($filename);
$data = kzo_jpeg_struct_get($image_file, TRUE);
for($ii=0; $ii<255; $ii++)
{
if(!isset($data['segments'][$ii])) break;
echo("\n");
echo("Segment #$ii\n");
foreach($data['segments'][$ii] as $key=>$value)
{
switch($key)
{
case 'APP':
$index=dechex(ord($value[1]));
$value=$marqueur_array[$index]
. " [0x$index] ($marqueur_legend_array[$index])";
break;
case 'Comment':
$value=htmlspecialchars(trim($value));
break;
case 'Version':
$major=ord($value[0]);
$minor=ord($value[1]);
$value = "".$major.".".$minor;
break;
case 'Length':
case 'Xdensity':
case 'Ydensity':
$value = (ord($value[0])<<8) + (ord($value[1]));
break;
case 'Units':
case 'XThumbnail':
case 'YThumbnail':
$value = ord($value[0]);
break;
case 'Identifier':
$value=trim($value);
break;
default:
$value="<... ".strlen($value)." bytes length ...>";
break;
}
echo("<strong>#$ii $key</strong>: $value\n");
}
}
echo("</pre>");
?>
Avec kzo_jpeg_struct_get (), vous pouvez obtenir la taille du scan contenu dans le fichier JPEG par :
<?php
if($result)
{
for($segment=0;$segment<count($result['segments']);$segment++)
{
if(isset($result['segments'][$segment]['scan']))
{
print(strlen($result['segments'][$segment]['scan']). " bytes");
break;
}
}
}
?>
mais le plus simple, si vous ne voulez que la taille du scan, est d’utiliser kzo_jpeg_scansize_get ().
Quelques liens utiles pour en savoir plus sur le format de fichier JPEG :
http://computing.ee.ethz.ch/sepp/xmedcon-0.8.13-mo.SEPP/xmedcon-0.8.13/libs/ljpg/read.c
http://cvsweb.xfree86.org/cvsweb/xc/programs/Xserver/XIE/mixie/jpeg/Attic/jwrjfif.c?rev=1.1.1.3
http://www.tug.org/tex-archive/support/jpeg2ps/readjpeg.c
http://www.cb1.com/ john/computing/emacs/lisp/graphics/jpeg-mode.el
http://www.mindspring.com/ nesssoft/src/jpginfo.txt
http://dev.w3.org/cvsweb/Amaya/libjpeg/jcmarker.c?rev=1.4&content-type=text/x-cvsweb-markup
http://www.w3.org/Graphics/JPEG/jfif.txt
http://www.fileformat.info/format/jpeg/
Les forums sont fermés.