PHP Lib JPEG

© Christian PAULUS. 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

Librairie de fonctions / PHP 4

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 :

NomMarqueurLegendDescription
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 :

MarqueurValeurLegend
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.

kzo_jpeg_struct_get ()

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)

JPEG

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_fileTRUE);
    
    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>");
?>

Zip - 2.6 ko
kzo_jpeg_struct_get. inc-2.zip

kzo_jpeg_scansize_get ()

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 ().

Zip - 2.2 ko
kzo_jpeg_struct_get. inc-2.zip

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/

Plussoyez !

Les forums sont fermés.