1 #LyX 1.3 created this file. For more info see http://www.lyx.org/
11 \paperpackage widemarginsa4
15 \use_numerical_citations 0
16 \paperorientation portrait
19 \paragraph_separation indent
21 \quotes_language english
25 \paperpagestyle default
29 Organización de Datos (75.06)
46 Leandro Lucarella (77891)
48 Ricardo Markiewicz (78226)
51 Primera Entrega, 28 de Junio del 2004
55 \begin_inset LatexCommand \tableofcontents{}
65 Método de compresión utilizado
68 Dada la asignación de confeccionar un compresor de archivos de cualquier
69 índole, con alguna optimización particular para archivos de texto, hemos
70 optado por la implementación del esquema:
72 Block Sorting + Move to front + Huffman Estático.
76 Si bien un compresor estadístico final más robusto como el
84 podrían producir niveles de compresión un tanto mejores, a fines de resguardar
85 la confección de un compresor estable y poseer tiempo suficiente para realizar
86 pruebas y optimizaciones, se optó por el
91 No obstante, se comparó con una implementación de
95 de ejemplo obtenida de Internet y se observaron que los resultados eran
96 muy similares, a veces obteniendo un mejor nivel de compresión y a veces
97 obteniendo uno peor, descartando luego de estas pruebas la posibilidad
98 de extender el estático al dinámico.
101 Además de la capacidad natural de todo compresor (esto es, de comprimir/descompr
102 imir), la implementación que describiremos a continuación cuenta con característ
103 icas especiales que se verán detallados en la
106 \begin_inset LatexCommand \ref{sec:Features-Especiales}
113 Dichas características se resumen a:
116 Persistencia del Modelo Orden-0 de
131 (Agrupación de Ceros, aplicado a la salida del
142 (Optimización para textos detallada posteriormente)
148 Antes de pasar a la descripción de la implementación de nuestro compresor,
149 detallaremos el modo de uso.
157 Como hemos ancitipado anteriormente, el compresor cuenta con features especiales
158 que pueden ser utilizados a través de opciones en la invocación del programa.
159 Antes de pasar a su descripción, notamos la invocación general para comprimir
160 y descomprimir un archivo como se pidió en el enunciado
170 es un enlace simbólico a
174 , nombre real del ejecutable.
186 ./grupo11 -c [-t volsize] sourcefile targetfile
195 el nombre del archivo a comprimir y
199 el nombre del archivo comprimido.
208 ./grupo11 -d sourcefile targetfile
217 el nombre del archivo a descomprimir y
221 el nombre del archivo descomprimido.
231 opcional que permite generar un archivo comprimido multivolumen, donde
232 volsize será el tamaño en kbytes de cada volúmen, excepto el último que
237 \begin_inset LatexCommand \label{sub:Execution-Flags}
244 Ademas de los flags standards que hemos visto recién, nuestro compresor
245 cuenta con otra serie de ellos para la utilización de los features especiales
246 que veremos más adelante.
247 A fines de documentar la totalidad de los flags de ejecución, detallamos
248 los anteriores y los adicionales a continuación:
250 \labelwidthstring 00.00.0000
256 Indica que se desea comprimir un archivo (mutualmente exclusivo con
260 , al menos uno debe estar presente).
262 \labelwidthstring 00.00.0000
268 Indica que se desea descomprimir un archivo (mutualmente exclusivo con
273 , al menos uno debe estar presente).
275 \labelwidthstring 00.00.0000
281 Indica que se desea un archivo comprimido en multivolumenes.
282 Seguido a dicho flag se debe indicar el tamaño en KBytes que se desea para
285 \labelwidthstring 00.00.0000
291 Puede ser utilizado únicamente en una compresión y activa el feature de
298 \labelwidthstring 00.00.0000
304 Puede ser utilizado únicamente en una compresión y graba el modelo de orden-0
309 generado durante la compresión del archivo (en un archivo de extensión
317 ), para que luego pueda ser reutilizado en otra compresión.
319 \labelwidthstring 00.00.0000
325 Puede ser utilizado únicamente en una compresión y carga un modelo de orden-0
330 para ser utilizado en la compresión del archivo especificado, evitando
331 el escaneado del archivo a comprimir.
332 Deberá ser sucedido por el nombre del archivo que posee el modelo.
334 \labelwidthstring 00.00.0000
340 Especifica la calidad (nivel) de compresión.
341 Puede ser un valor entre 0 y 9, siendo 0 el menor nivel de compresión (más
342 rápido) y 9 el máximo (más lento).
343 Por omisión se utiliza un nivel de compresión 5.
344 \layout Subsubsection*
349 Damos a continuación unos breves ejemplos de invocación utilizando diferentes
353 Compresión multivolumen (de 1024KB, cada uno):
357 ./grupo11 -c -t 1024 libro.txt libro.j
368 ./grupo11 -cz libro.txt libro.j
371 Compresión grabando modelo de
379 ./grupo11 -cs libro.txt libro.j
382 Compresión con carga de
390 ./grupo11 -c libro.txt libro.j -m modelo.ftb
393 Compresión de máxima calidad y volúmenes de 100KB:
397 ./grupo11 -czt100 -q9 libro.txt libro.j
400 Descompresión de cualquiera de los anteriores:
404 ./grupo11 -d libro.j libro_descomprimido.txt
419 La idea básica del move to front es mantener una lista que represente los
420 símbolos del archivo o bloque a procesar, y a su vez coloca los símbolos
421 mas frecuentes al frente de esta lista.
428 \begin_inset Quotes eld
431 aaaabbabbbaaaaaccccbbccbbbbdddddbbbb
432 \begin_inset Quotes erd
439 \begin_inset Quotes eld
443 \begin_inset Quotes erd
449 Salida: 0 0 0 0 1 0 1 1 0 0 1 0 0 0 2 0 0 0 2 0 1 0 1 0 0 0 3 0 0 0 1 0
453 Un símbolo es codificado como el índice (ó posición) en la lista de símbolos
454 inicial (la cual contiene a todos los símbolos diferentes del archivo o
456 Al comenzar el proceso, se leen uno por uno los símbolos del archivo o
457 bloque original y este mismo símbolo es promovido hacia el frente de la
458 lista, de esta los símbolos mas frecuentes tienden a posicionarse al frente
462 Como este esquema es aplicado luego de ser procesado por el
466 tenemos la seguridad que existirá una fuerte localidad de símbolos en el
467 bloque de datos recibido, esto provocará que la salida del
471 posea una gran cantidad de cadenas de ceros consecutivos, que luego pueden
472 ser codificados nuevamente, lo que favorece la compresión final.
478 Si bien no ahondaremos en detalles de implementación que pueden observarse
479 en la documentación generada por doxygen que acompaña este informe, pasamos
480 a presentar la interfaz a través de la cual el usuario podrá utilizar este
482 Antes, es necesario comentar que el estado del compresor, se mantiene a
483 través de una estructura definida como
487 , en la cual se especificarán cosas tales como si el compresor actua sobre
488 archivos o chunks de datos, si es un huffman canonico o standard, archivo
489 a comprimir, archivo destino, etc.
494 El compresor y/o descompresor Huffman Estático, será inicializado y desinicializ
495 ado utilizando las rutinas:
501 HUFF_STATE *shuff_init_encoder_byfile(char *inputfile, char *outputfile,
508 HUFF_STATE *shuff_init_encoder_bychunk(char *outputfile, long volsize);
514 HUFF_STATE *shuff_init_decoder(char *inputfile, char *outputfile);
520 void shuff_deinit_encoder(HUFF_STATE *shuff);
526 void shuff_deinit_decoder(HUFF_STATE *shuff);
529 Para llevar a cabo la compresión efectiva de un archivo o chunks de datos,
530 se cuentan con las siguientes rutinas:
535 int shuff_encode_file(HUFF_STATE *shuff);
540 int shuff_decode_file(HUFF_STATE *shuff);
545 int shuff_scanfreq_chunk(HUFF_STATE *shuff, char* chunk, int chunksize);
550 int shuff_decode_chunk(HUFF_STATE *shuff, char *chunk, int chunksize, int
554 Operación sobre archivos o chunks
559 Dado que se requería la utilización de este compresor en la etapa final
560 de un BS+MTF, el mismo proporciona funcionalidad para comprimir directamente
561 un archivo especificado, o bien para realizar la compresión de chunks de
562 datos, que en nuestro caso serán las salidas del Move to Front.
565 Persistencia del Modelo Estadístico de Orden 0
570 A fines de poder grabar o cargar un modelo de orden-0 el cual simplemente
571 consiste en una tabla de frecuencias/probabilidades de los 255 symbolos
572 posibles en un archivo, dando lugar al Huffman Canónico que será explicado
573 posteriormente, se cuenta con dos funciones:
583 \begin_inset LatexCommand \label{sec:Features-Especiales}
587 Optimizaciones y Características adicionales
590 Como fue anticipado al inicio de este documento, nuestro compresor cuenta
591 con funcionalidad extra que permite en ciertos casos obtener mejores niveles
593 Pasamos a describir las mismas una por una, terminando por último con una
594 optimización específica para textos.
600 Dada la naturaleza del Huffman Estático que hemos implementado como el compresor
601 estadístico final de la cadena
605 , el mismo se vale de un modelo estadístico de orden-0, el cual es obtenido
606 realizando una pasada inicial al archivo a comprimir, en la cual obtiene
607 una tabla de frecuencias/probabilidades, y la cual es utilizada para generar
608 el árbol de Huffman, que a su vez da origen a una tabla de códigos prefijos
609 que finalmente es utilizada en el compresor, para codificar los símbolos
610 o caracteres del archivo original.
613 Dicho esto, destacamos la extensión que hemos realizado a nuestro compresor
614 de Huffman para que pueda guardar y/o cargar un modelo estadístico de orden-0
615 y el usuario pueda por ejemplo utilizar para comprimir cualquier archivo
616 de texto, un modelo que él crea óptimo para la compresión de dichos archivos,
617 en vez de generar un modelo diferente para cada archivo que comprime.
620 Esta capacidad de un compresor de Huffman, se la conoce como Huffman Canónico,
621 y se encuentra presente en nuestro compresor.
622 Para saber más sobre su modo de uso, dirigirse a la sección
625 \begin_inset LatexCommand \ref{sub:Execution-Flags}
637 Este algoritmo se aplica a la salida del
645 que aumenta la localidad, genera estadísticamente muchas secuencias de
647 Como el Huffman Estático no aprovecha esta característica (comprime igual
656 ), se buscó un método que sí la explote para optimizar el compresor y se
657 llegó a un algoritmo muy simple que bautizamos
664 Cada secuencia de ceros se codifica con 2 bytes, el primero es siempre 0
669 ) y el segundo indica la cantidad de ceros que le siguen.
670 En el caso de haber un byte de valor cero aislado, también se codifica
675 , que indica que viene un cero y luego de ese cero no viene ningún cero
676 más), expandiendo la salida, pero estos son casos aislados que estadísticamente
677 se ven superados por la cantidad de secuencias largas de ceros que son
678 comprimidas a sólo 2 bytes.
679 Además, la salida del
683 (Zero Grouping) es comprimida con Huffman por lo que en casos extremos
684 la expansión no se manifiesta en forma notoria.
687 Como la cantidad de ceros que le siguen al primero en una secuencia es expresada
688 con un byte, sólo se pueden comprimir a 2 bytes secuencias de hasta 256
689 ceros (el primer cero más los 0-255 siguientes).
690 De haber secuencias con mayor cantidad de ceros, simplemente se generan
703 la cantidad de ceros en la secuencia dividido 256, redondeando hacia arriba)
705 Por ejemplo, una secuencia de 257 ceros será expresada como
709 (2 grupos) y una de 525 como
711 0x00 0xFF 0x00 0xFF 0x00 0x0B
714 Nuevamente, se comprobó estadísticamente que las secuencias de ceros rara
715 vez superan los 50 ceros seguidos, por lo que de utilizar más de un byte
716 para expresar la cantidad de ceros que siguen al primero se obtendrían
718 \layout Subsubsection*
725 Salida de MTF: 0 0 0 0 0 0 1 5 3 0 0 0 0 12 0 1 0 0 0 0 0 0 0 0 0 1 1
731 Salida de ZG: 0 5 1 5 3 0 3 12 0 0 1 0 8 1 1
747 Como se puede ver, la salida del MTF es de 33 bytes, mientras que la del
752 es de 22 (incluso cuando hubieron expansiones).
753 Como se podrá ver en las pruebas del capítulo
754 \begin_inset LatexCommand \vref{cha:Benchmarks}
758 , en la mayoría de los casos se logra una mejora introduciendo este algoritmo,
759 y en casos extremos esta mejora llega obtener resultados con la mitad de
760 bpb (bits por byte) que la salida original del
770 Esta optimización se ha realizado específicamente para mejorar la compresión
771 de archivos de texto.
772 La base de esta técnica es la previa confección de un diccionario de palabras
773 (en nuestro caso 255 palabras máximo), a través del cual aplicando un pre-proce
774 samiento al archivo a comprimir, reemplazamos las palabras de ese diccionario
775 que se encuentren en el archivo, por un código de escape sucedido por el
776 índice en el diccionario de la palabra que se abrevia.
779 Es decir, si tenemos el siguiente diccionario de 4 palabras:
795 ; y poseemos el texto:
798 \begin_inset Quotes eld
810 \begin_inset Quotes erd
815 , luego del pre-procesamiento tendremos:
818 \begin_inset Quotes eld
834 \begin_inset Quotes erd
842 Para la confección de un buen diccionario, hemos desarrollado una utilidad
843 que contabiliza las 255 palabras que más aparecen dentro de una fuente
844 especificada, y luego del análisis de varios textos en castellano de toda
845 índole (informáticos, novelas, noticias), se obtiene el diccionario que
846 será entregado con el software.
849 Documentación de la API
852 Para obtener una documentación de la API, se incluye en formato HTML en
853 el CD-ROM la documentación generada con Doxygen para los distintos componentes
855 Esta documentación se encuentra en el directorio
863 \begin_inset LatexCommand \label{cha:Benchmarks}
870 Prueba Calgary Corpus
873 El set de prueba Calgary Corpus Test es utilizado internacionalmente para
874 la prueba y comparación de compresores, contando con archivos diseñados
875 especificamente para estos fines.
876 Es por ello que hemos utilizado dicho set y a continuación exponemos los
880 Bench 1) JACU vs GZIP vs BZIP2
883 Se prueba el set de Calgary utilizando nuestro compresor, y enfrentandolo
884 al GZIP y BZIP2 en términos de tiempo utilizado para la compresion y nivel
885 de compresión (bits per byte).
886 Los resultados a continuación:
888 \begin_inset Float table
895 Comparación de compresores JACU, GZIP y BZIP2 con Test de Calgary Corpus
900 <lyxtabular version="3" rows="19" columns="7">
902 <column alignment="center" valignment="top" leftline="true" width="0">
903 <column alignment="center" valignment="top" leftline="true" width="0">
904 <column alignment="center" valignment="top" leftline="true" width="0">
905 <column alignment="center" valignment="top" leftline="true" width="0">
906 <column alignment="center" valignment="top" leftline="true" width="0">
907 <column alignment="center" valignment="top" leftline="true" width="0">
908 <column alignment="center" valignment="top" leftline="true" rightline="true" width="0">
909 <row topline="true" bottomline="true">
910 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
920 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
930 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
940 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
950 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
960 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
970 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
982 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
990 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1000 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1010 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1020 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1030 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1040 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1051 <row topline="true">
1052 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1060 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1070 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1080 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1090 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1100 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1110 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1121 <row topline="true">
1122 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1130 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1140 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1150 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1160 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1170 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1180 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1191 <row topline="true">
1192 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1200 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1210 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1220 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1230 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1240 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1250 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1261 <row topline="true">
1262 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1270 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1280 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1290 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1300 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1310 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1320 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1331 <row topline="true">
1332 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1340 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1350 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1360 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1370 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1380 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1390 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1401 <row topline="true">
1402 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1410 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1420 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1430 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1440 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1450 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1460 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1471 <row topline="true">
1472 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1480 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1490 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1500 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1510 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1520 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1530 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1541 <row topline="true">
1542 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1550 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1560 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1570 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1580 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1590 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1600 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1611 <row topline="true">
1612 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1620 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1630 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1640 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1650 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1660 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1670 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1681 <row topline="true">
1682 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1690 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1700 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1710 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1720 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1730 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1740 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1751 <row topline="true">
1752 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1760 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1770 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1780 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1790 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1800 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1810 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1821 <row topline="true">
1822 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1830 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1840 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1850 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1860 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1870 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1880 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1891 <row topline="true">
1892 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1900 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1910 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1920 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1930 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1940 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1950 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
1961 <row topline="true">
1962 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1970 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1980 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
1990 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2000 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2010 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2020 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
2031 <row topline="true">
2032 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2040 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2050 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2060 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2070 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2080 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2090 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
2101 <row topline="true">
2102 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2110 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2120 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2130 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2140 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2150 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2160 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
2171 <row topline="true" bottomline="true">
2172 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2180 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2187 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2197 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2207 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2214 <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
2224 <cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">