zlib.deflate y zlib.inflate
zlib.deflate (compresión) y
zlib.inflate (descompresión) son las implementaciones
de los métodos de compresión presentados en la
» RFC 1951.
El filtro deflate toma hasta tres parámetros, pasados
en forma de array asociativo.
level especifica el nivel de compresión deseado,
de 1 a 9. Cuanto más alto sea el nivel, mejor será la compresión, y más
costoso será el coste de compresión. Existen dos niveles de compresión especiales:
0, que representa la ausencia de compresión, y -1, que representa el nivel por defecto de zlib:
actualmente, 6.
window es el logaritmo en base 2 del tamaño de la
ventana de compresión. Los valores superiores, hasta 15, es decir, 32768 bytes,
dan una mejor compresión a costa de más memoria, y los valores inferiores,
hasta 9, es decir, 512 bytes, dan una compresión menor ocupando menos
espacio en memoria. Por defecto,
window vale actualmente 15.
El filtro zlib.deflate implementa los métodos de
compresión DEFLATE, ZLIB y
GZIP según el valor del parámetro
window.
Los 4 bits inferiores del parámetro window fijan el tamaño del
«búfer de historial» interno utilizado, siendo el logaritmo en base 2 de su
tamaño, en un rango de 8 a 15. El significado de los demás bits del
parámetro window puede fijarse como se describe a continuación.
-
DEFLATE (» RFC 1951)
es un algoritmo de compresión sin tratar, sin encabezado ni suma de
verificación. Se aplica cuando el parámetro window se fija en el rango
de -9 a -15. Este algoritmo de compresión es la base de todos los
formatos generados por el filtro zlib.deflate.
Las funciones correspondientes que operan directamente sobre strings son
gzdeflate() y gzinflate().
-
ZLIB (» RFC 1950)
aplica el algoritmo DEFLATE y añade un encabezado de
2 bytes y un tráiler de 4 bytes que contiene la suma de verificación
Adler32 de los datos sin comprimir, en orden de bytes big-endian:
ZLIB = ZLIBHEADER(2B) DEFLATE ADLER32(4B)
El encabezado de 2 bytes, leído como un número de 16 bits sin signo en
orden big-endian, debe ser múltiplo de 31.
Este formato se genera cuando el parámetro window se fija en el rango
de 8 a 15.
Las funciones correspondientes que operan directamente sobre strings son
gzcompress() y gzuncompress().
-
GZIP (» RFC 1952)
aplica el algoritmo DEFLATE añadiendo un encabezado y
un tráiler con la suma de verificación CRC32 de los
datos sin comprimir y su longitud, ambos en orden de bytes little-endian:
GZIP = GZIPHEADER(10B) DEFLATE CRC32(4B) LENGTH(4B)
Es el formato de los ficheros .gz, en el que
GZIPHEADER contiene, en este orden, la firma
GZIP (\x1f\x8B), el método de
compresión (\x08), un byte de flags a cero, una fecha
de modificación a cero en 4 bytes, un byte de flags adicionales que
depende del nivel de compresión, y el sistema operativo fijado al sistema
actual (\x00 = sistema de ficheros FAT,
\x03 = Unix, etc.).
Este formato se genera cuando el parámetro window se fija en el rango
de 9+16=25 a 15+16=31. Tenga en cuenta que existe un límite de 4GB para
la longitud máxima de los datos sin comprimir; más allá de este límite,
solo se almacena el módulo 2^32 de la longitud real en la parte
LENGTH.
Las funciones correspondientes que operan directamente sobre strings son
gzencode() y gzdecode(); la
función gzopen() permite leer y escribir ficheros
.gz.
Con el filtro
zlib.inflate, solo se admite el parámetro
window; cualquier otro parámetro
(
memory,
level) se ignora.
Sea $W el logaritmo en base 2 del tamaño del búfer de historial, de modo
que el descompresor asigna 2^$W bytes. Para el formato ZLIB, este valor
debe ser mayor o igual al registrado en el encabezado, lo cual se
comprueba durante la descompresión; para los demás formatos, basta con
que sea lo suficientemente grande para las distancias de coincidencia
realmente presentes en los datos.
El rango es 9 ≤ $W ≤ 15. Si se desconoce, $W=15 es la opción más segura.
-
DEFLATE (» RFC 1951):
utilice window=-$W, siendo $W un valor no inferior al utilizado para
la compresión. Si se desconoce, fije window=-15.
-
ZLIB (» RFC 1950):
utilice window=$W. El valor de $W puede obtenerse del propio encabezado
ZLIB; en caso contrario, fije window=15.
-
GZIP (» RFC 1952):
utilice window=$W+16. Un encabezado GZIP no contiene el tamaño de la
ventana, por lo que debe fijarse window=31, salvo que se conozca el valor
utilizado para la compresión.
-
ZLIB o GZIP:
utilice window=$W+32 para la detección automática del encabezado, de
modo que ambos formatos puedan reconocerse y descomprimirse;
window=15+32=47 es la opción más segura.
memory es una escala que indica cuánta memoria de
trabajo debe asignarse.
Los valores válidos van de 1, para la asignación mínima, a 9, para una
asignación máxima. La asignación de memoria afecta únicamente a la velocidad
de ejecución y no influye en el tamaño de los datos generados.
Nota:
Como el nivel de compresión es el parámetro más común, también puede ser proporcionado
como valor int, en lugar de un array.
Los filtros de compresión zlib.* están disponibles si el soporte de
zlib está activado.
Ejemplo #1
zlib.deflate y
zlib.inflate
<?php
$params = array('level' => 6, 'window' => 15, 'memory' => 9);
$original_text = "This is a test.\nThis is only a test.\nThis is not an important string.\n";
echo "El texto original tiene " . strlen($original_text) . " caracteres.\n";
$fp = fopen('test.deflated', 'w');
stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_WRITE, $params);
fwrite($fp, $original_text);
fclose($fp);
echo "El fichero comprimido tiene " . filesize('test.deflated') . " bytes.\n";
echo "El texto original era:\n";
/* Utiliza readfile y zlib.inflate para descomprimir al vuelo */
readfile('php://filter/zlib.inflate/resource=test.deflated');
/* Muestra:
El texto original tiene 70 caracteres.
El fichero comprimido tiene 56 bytes.
El texto original era:
This is a test.
This is only a test.
This is not an important string.
*/
?>
Ejemplo #2
zlib.deflate simple
<?php
$original_text = "This is a test.\nThis is only a test.\nThis is not an important string.\n";
echo "El texto original tiene " . strlen($original_text) . " caracteres.\n";
$fp = fopen('test.deflated', 'w');
/* Aquí, "6" indica el nivel de compresión de 6 */
stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_WRITE, 6);
fwrite($fp, $original_text);
fclose($fp);
echo "El fichero comprimido tiene " . filesize('test.deflated') . " bytes.\n";
/* Muestra:
El texto original tiene 70 caracteres.
El fichero comprimido tiene 56 bytes.
*/
?>
bzip2.compress y bzip2.decompress
bzip2.compress y
bzip2.decompress
funcionan de la misma manera que los filtros zlib descritos anteriormente.
El filtro bzip2.compress acepta hasta 2 parámetros,
en forma de array asociativo:
blocks es un valor int, de 1 a 9,
especificando el número de bloques de 100 kb de memoria a asignar al espacio de
trabajo.
work es también un int cuyo valor va de
0 a 250, e indica el nivel de esfuerzo proporcionado con un método de
compresión antes de pasar a otro método, más lento pero más fiable. Modificar este
parámetro solo tiene efecto en la velocidad de compresión. La ganancia de espacio
o la memoria utilizada permanecen iguales. Un nivel de 0 indica que la
biblioteca debe utilizar su configuración por defecto.
El filtro bzip2.decompress acepta únicamente un parámetro,
que puede ser pasado en forma de bool, o como el elemento
small de un array asociativo.
small, cuando se define a true, indica a la
biblioteca bzip que debe realizar una descompresión utilizando la menor cantidad de memoria posible, a expensas de la velocidad.
Los filtros bzip2.* están disponibles si el soporte de
bz2 está activado.
Ejemplo #3
bzip2.compress y
bzip2.decompress
<?php
$param = array('blocks' => 9, 'work' => 0);
echo "El fichero original tiene " . filesize('LICENSE') . " bytes.\n";
$fp = fopen('LICENSE.compressed', 'w');
stream_filter_append($fp, 'bzip2.compress', STREAM_FILTER_WRITE, $param);
fwrite($fp, file_get_contents('LICENSE'));
fclose($fp);
echo "El fichero comprimido tiene " . filesize('LICENSE.compressed') . " bytes.\n";
/* Muestra:
El fichero original tiene 3288 bytes.
El fichero comprimido tiene 1488 bytes.
*/
?>