\chapter{Kakadu}

\section{Introducción}
Kakadu \cite{Taubman.kakadu} es una implementación propietaria de
la Parte 1 del estándar JPEG2000, realizada por David Taubman.
Existen otras implementaciones \cite{jasper}, pero ésta es quizás
la mas eficiente. En el presente capítulo se dará una breve
descripción de la versión 4.0 de Kakadu.

\section{Características}

El núcleo del sistema está escrito en C++ y ha sido implementado
con la intención de ser totalmente independiente de plataforma. La
plataforma destino debe al menos soportar enteros de 32 bits. El
código está especialmente optimizado para procesadores Pentium.

Debido a la complejidad del estándar JPEG2000, los puntos en los
que se ha centrado la implementación de Kakadu son: el uso de la
memoria, la velocidad de ejecución, y el ofrecer una arquitectura
altamente flexible, con el fin de cubrir las necesidades de una
amplia variedad de aplicaciones, desde meros
compresores/descompresores hasta complejas aplicaciones
interactivas o sistemas cliente/servidor.

\section{Organización}

El núcleo de la implementación de Kakadu es lo que denominamos el
sistema base, o \emph{core system}. Es un conjunto de clases que
proporcionan la funcionalidad necesaria para interaccionar con los
\emph{codestreams} del estándar JPEG2000, según la especificación
de la Parte 1. Este núcleo está diseñado para ser totalmente
portable a cualquier plataforma. Basándose en este núcleo, se crea
otro conjunto de clases para proporcionar funcionalidad adicional,
como es el soporte del protocolo JPIP definido en la Parte 9 del
estándar o el soporte para diferentes archivos de imágenes (.JP2,
.MJ2, etc.). Se añade además un conjunto de aplicaciones con el
fin de demostrar el funcionamiento de dichas clases. Tan sólo el
\emph{core system} es totalmente portable. En el resto de la
implementación de Kakadu, habrá partes portables y otras, en
cambio, necesitarán de las correspondientes modificaciones para
ser portadas. Todo el código de Kakadu está escrito empleando el
lenguaje de programación C++.

\subsection{Sistema base (\emph{core system})}

El conjunto de clases que forman el sistema base está dividido en
subsistemas atendiendo a su funcionalidad. La figura
\ref{fig:baseKakadu} muestra los principales subsistemas del
sistema base de Kakadu (no refleja el subsistema para el
procesamiento de la ROI). Las líneas de puntos vinculan clases del
sistema base con representaciones internas de la arquitectura de
un \emph{codestream}. Las instancias de estas clases actúan a modo
de interfaz, es decir, ofrecen una serie de servicios con los
cuales operar con los elementos asociados, pero no almacenan nada.

\begin{figure}[!hbt]
  \begin{center}
    \resizebox{\textwidth}{!}{\input{figuras/baseKakadu}}
    \caption{Sistema base de Kakadu.}
    \label{fig:baseKakadu}
  \end{center}
\end{figure}

Los principales subsistemas del sistema base son los siguientes:

\begin{itemize}

\item \textbf{Subsistema de parámetros (\emph{Coding Parameter
Sub-System})}: Los parámetros de codificación incluidos en un
\emph{codestream}, y que son necesarios para de descodificación
adecuada de la imagen, está repartidos por un conjunto de
marcadores, como son SIZ, COD, COC, etc. Estos están situados en
diferentes partes, como la cabecera principal, la del \emph{tile}
o la del \emph{tile-part}, y se sobreescriben unos a otros en
función de su posición. El subsistema de parámetros es un conjunto
de clases, todas ellas derivadas de la clase \emph{kdu\_params},
cuyas instancias se organizan internamente mediante listas
multidimensionales para reflejar la jerarquía real de los
parámetros. Estas clases ofrecen una interfaz cómoda y eficaz. La
mayor parte de la interacción con el subsistema de parámetros se
realiza a través del objeto raíz de toda la jerarquía de objetos,
el cual siempre será una instancia de la clase \emph{siz\_params}.
Se tiene acceso a este objeto a través de la clase
\emph{kdu\_codestream}.

Las principales clases incluidas en este subsistema son las
siguientes:

\begin{itemize}

\item \emph{crg\_params}: Para albergar la información de los
marcadores CRG.

\item \emph{poc\_params}: Para albergar la información de los
marcadores POC.

\item \emph{rgn\_params}: Para albergar la información de los
marcadores RGN.

\item \emph{qcd\_params}: Para albergar la información de los
marcadores QCD.

\item \emph{siz\_params}: Para albergar la información del
marcador SIZ. Además es la clase del objeto raíz de toda la
jerarquía interna de objetos de parámetros.

\item \emph{org\_params}: No contiene información de ningún
marcador en especial sino que contiene información acerca de la
organización del \emph{codestream}, como por ejemplo, la
estructuración de los \emph{tile-parts}.

\item \emph{cod\_params}: Para albergar la información de los
marcadores COD.

\end{itemize}

\item \textbf{Subsistema para la gestión de la imagen comprimida
(\emph{Compressed Image Management Sub-System})}: Es quizás el
subsistema más importante de todo el sistema base. Está formado
por una jerarquía de clases, cada una de las cuales ofrece una
interfaz para operar con un tipo determinado de partición de la
imagen almacenada en el \emph{codestream} (\emph{tile},
\emph{tile-component}, resolución, precinto, etc.). La raíz es la
clase \emph{kdu\_codestream}. A partir de esta clase se accede al
resto de clases que representan un tipo de partición, como
\emph{kdu\_tile} para el \emph{tile}, \emph{kdu\_resolution} para
la resolución, \emph{kdu\_subband} para la subbanda, etc. La
partición más pequeña de la cual se ofrece una clase interfaz es
el \emph{code-block}, con la clase \emph{kdu\_block}.

Las principales clases incluidas en este subsistema son las
siguientes:

\begin{itemize}

\item \emph{kdu\_codestream}: Es la clase principal, mediante la
cual se tiene acceso al resto de clases.

\item \emph{kdu\_tile}: Representa a un tile determinado.

\item \emph{kdu\_tile\_comp}: Representa a un tile-component
determinado. Se tiene acceso a través de la clase anterior.

\item \emph{kdu\_resolution}: Representa a una resolución
determinada. Se tiene acceso a través de la clase anterior.

\item \emph{kdu\_subband}: Representa a una subbanda determinada.
Se tiene acceso a través de la clase anterior.

\item \emph{kdu\_precinct}: Representa a un precinto determinado.
Se tiene acceso a través de la clase \emph{kdu\_resolution}.

\item \emph{kdu\_block}: Representa a un \emph{code-block}
determinado. Se tiene acceso a través de la clase anterior.

\end{itemize}

\item \textbf{Subsistemas de procesamiento de los datos
(\emph{Data Processing Sub-systems})}: Este es el conjunto de los
subsistemas que identifican a cada una de las etapas del
procesamiento de la imagen, como es la transformada DWT, la
cuantificación, la codificación o la transformada de color, si
existiese. Cada uno de ellos contiene un conjunto de clases con el
código necesario para llevar a cabo dicha etapa. Cabe decir que
todas estas clases interaccionan con el \emph{codestream} mediante
la interfaz de las clases \emph{kdu\_resolution},
\emph{kdu\_subband} y \emph{kdu\_block}, mencionadas
anteriormente.

Todas las clases de estos subsistemas son derivadas, para la
compresión, de la clase \emph{kdu\_push\_ifc}, y para la
descompresión, de la clase \emph{kdu\_pop\_ifc}.

Las principales clases del subsistema encargado de la transformada
DWT son:

\begin{itemize}
\item \emph{kdu\_analysis}: Para la transformada DWT.

\item \emph{kdu\_synthesis}: Para la inversa de la transformada
DWT.
\end{itemize}

Las principales clases del subsistema encargado de la
codificación/descodificación son:

\begin{itemize}
\item \emph{kdu\_encoder}: Para la codificación.

\item \emph{kdu\_decoder}: Para la descodificación.
\end{itemize}

\end{itemize}

Como se ha mencionado, la clase \emph{kdu\_codestream} es la clase
central del subsistema encargado de ofrecer acceso a las diversas
particiones de una imagen y, además, de servir de soporte al resto
de los subsistemas. Se podría decir que la clase más importante
del sistema base de Kakadu es la clase \emph{kdu\_codestream}.

Un objeto instancia de la clase \emph{kdu\_codestream} se
inicializa mediante un objeto de la clase
\emph{kdu\_compressed\_source}, que identifica una fuente de datos
comprimidos, un \emph{codestream}. El tipo de fuente de datos
puede ser la combinación de uno o más de los siguientes tipos:

\begin{itemize}

\item Secuencial (\emph{Sequential}): Obliga a que los datos sean
leídos secuencialmente, desde el principio al fin.

\item De acceso aleatorio (\emph{Seekable}): Permite acceder
aleatoriamente a los datos.

\item Con \emph{cache} (\emph{Cached}): La fuente de los datos
tiene la estructura de una \emph{cache}, organizada en
\emph{data-bins}, según especifica el protocolo JPIP.

\end{itemize}

La clase \emph{kdu\_compressed\_source} es una clase abstracta.
Kakadu incluye un conjunto de clases, derivadas de esta clase, con
el fin de dar soporte a diferentes fuentes de datos (archivos J2C
\emph{raw}, JP2, MJ2, etc.). Estas clases ya no forman parte del
sistema base.

Con el fin de minimizar el uso de memoria, todos los objetos del
sistema son destruidos una vez se dejen de utilizar. Cuando se
''accede'' a un determinado elemento, se crea la interfaz
apropiada para trabajar con él. Cuando se ''cierra'' dicho
elemento, se destruye. Por ejemplo, ejecutando el método
\emph{open\_tile} de la clase \emph{kdu\_codestream}, se tiene
acceso a un \emph{tile} determinado, creándose un objeto de la
clase \emph{kdu\_tile}. Al cerrar el \emph{tile} llamando al
método \emph{close} de la clase \emph{kdu\_tile}, la información
de dicho \emph{tile} es eliminada, por lo que no se podrá volver a
acceder a él. Este es el comportamiento por defecto, aunque puede
ser deshabilitado, haciendo que todos los recursos sean
persistentes, con el método \emph{set\_persistent} de la clase
\emph{kdu\_codestream}.

\subsection{Clases para el acceso a archivos}

Kakadu, en su versión 4.0 ofrece soporte completo para el
tratamiento de archivos con formato JP2 y MJ2. Se espera que en
versiones posteriores se de soporte para los formatos JPX y JPM.
Los archivos \emph{raw} J2C, que contienen un \emph{codestream}
únicamente, también son soportados.

Las principales clases para el acceso a los archivos son las
siguientes:

\begin{itemize}

\item \emph{jp2\_source}: Permite el acceso a los archivos JP2.

\item \emph{mj2\_video\_source}: Permite el acceso a los archivos
MJ2.

\item \emph{kdu\_simple\_file\_source}: Permite el acceso a
cualquier tipo de archivo sin estructura definida, como los J2C.

\end{itemize}

Todas estas clases derivan de la clase
\emph{kdu\_compressed\_source}. Son prácticamente portables a
cualquier plataforma.

\subsection{Clases para el soporte del protocolo JPIP}

Kakadu ofrece el soporte necesario para desarrollar aplicaciones
cliente/servidor empleando el protocolo JPIP, definido en la Parte
9 del estándar JPEG2000. En realidad, Kakadu realiza su propia
implementación, variando ligeramente la especificación del
protocolo.

Las principales clases que dan soporte al protocolo JPIP son las
siguientes:

\begin{itemize}

\item \emph{kdu\_cache}: Es una clase derivada de la clase
\emph{kdu\_compressed\_source}, y su misión es proveer una fuente
de datos con estructura de \emph{cache}. Esta clase es
especialmente empleada en aplicaciones cliente/servidor, como las
que se pueden desarrollar basándose en el protocolo JPIP. En la
\emph{cache}, los datos son organizados en \emph{data-bins}. La
clase ofrecerá la posibilidad de eliminar de la \emph{cache} los
\emph{data-bins} que hace más tiempo que fueron usados.

\item \emph{kdu\_client}: Implementa un completo cliente JPIP.
Deriva de la clase \emph{kdu\_cache}. Su implementación no es
independiente de plataforma, ya que está diseñada para correr bajo
sistemas Windows. Si se quisiera pasar a otro sistema operativo,
habría que cambiar la parte de utilización de sockets y creación
de hilos.

\item \emph{kdu\_serve}: Proporciona el componente independiente
de plataforma necesario para la creación de un servidor JPIP. La
aplicación \emph{kdu\_server} hace uso de esta clase.

\end{itemize}

\subsection{Clases para la reconstrucción de la imagen}

Para la reconstrucción de la imagen, a partir de un
\emph{codestream}, identificado por un objeto de la clase
\emph{kdu\_codestream}, Kakadu sólo pone a disposición la clase
\emph{kdu\_region\_decompressor}.

Esta clase es especialmente útil para aplicaciones que requieren
una descompresión interactiva, como visualizadores o editores de
imágenes.

Para reconstruir una región de una imagen tan sólo le
especificamos al objeto de la clase
\emph{kdu\_region\_decompressor} la referencia al objeto de la
clase \emph{kdu\_codestream} que identifica a la imagen y qué
región es, abstrayéndonos del procedimiento necesario a seguir
para conseguir tal fin.

La reconstrucción de una región de la imagen es dividida en
etapas, cuyo número depende del tamaño del \emph{buffer} que
disponga el objeto para llevar a cabo la tarea.

La implementación de esta clase es totalmente independiente de
arquitectura.

\subsection{Aplicaciones de ejemplo}

Todas las aplicaciones de ejemplo incluidas en la versión 4.0 de
Kakadu pueden correr en los sistemas Windows, Linux y Solaris, a
excepción de \emph{kdu\_client} y \emph{kdu\_server}, diseñadas
únicamente para correr en sistemas Windows.

Algunas de las aplicaciones de ejemplo son las siguientes:

\begin{itemize}

\item \emph{kdu\_compress}: Permite la compresión de imágenes,
almacenadas en otros formatos como RAW, BMP, PPM o PGM, mediante
el estándar JPEG2000. El formato de salida puede ser o bien J2C o
JP2. Como parámetros se le pasa el tipo de compresión/codificación
a realizar, el tamaño de los precintos, de los \emph{code-blocks},
el número de \emph{tiles}, el tipo de progresión, etc.

\item \emph{kdu\_v\_compress}: Como archivo de entrada acepta un
archivo con formato VIX, que consiste en un secuencia de imágenes de
vídeo en formato \emph{raw} con una cabecera de texto, y produce
como salida un archivo MJ2 con la compresión del vídeo según el
estándar JPEG2000.

\item \emph{kdu\_maketlm}: Permite añadir a un archivo de imagen,
ya sea en formato J2C o en formato JP2, los marcadores TLM
(generalmente, sólo habrá uno). Se le puede indicar al compresor,
\emph{kdu\_compress}, que incluya también los marcadores PLT, pero
la inclusión de los marcadores TLM se hace de forma independiente
con esta aplicación.

\item \emph{kdu\_expand}: Permite descomprimir una imagen
JPEG2000, almacenada en un archivo J2C o en un archivo JP2. El
formato de salida puede ser RAW, BMP, PGM o PPM. La aplicación
ofrece la posibilidad de descomprimir sólo un área de la imagen.

\item \emph{kdu\_v\_expand}: Descomprime la secuencia de vídeo
almacenada en un archivo MJ2 y produce un archivo con formato VIX.

\item \emph{kdu\_transcode}: A partir de un archivo de imagen
JPEG2000, esta aplicación permite cambiar la
compresión/codificación de la misma. Tiene el mismo efecto que si
descomprimiéramos la imagen y la volviésemos a comprimir con unos
parámetros de compresión diferentes.

\item \emph{kdu\_show}: Es la aplicación estrella de Kakadu. Se
trata de un visualizador interactivo de imágenes. Permite
visualizar imágenes locales, en formato JP2, JPX o J2C, pero
también permite visualizar imágenes remotas actuando a modo de
cliente JPIP.

\item \emph{kdu\_hyperdoc}: Es una herramienta para generar la
documentación en formato HTML de las clases a partir de los
comentarios incluidos en su código fuente. También es empleada en
Kakadu para crear las interfaces Java de las clases.

\item \emph{kdu\_server}: Es un servidor JPIP.

\end{itemize}

\section{Compatibilidad con Java}

Empleando la API JNI \cite{java}, Kakadu ofrece la posibilidad de
construir clases interfaces en Java para las clases escritas en
C++. La razón de la inclusión en Kakadu de esta posibilidad es
para intentar dar una solución a las dependencias de la
arquitectura de algunas aplicaciones. Aunque el sistema base y
muchas de las aplicaciones incluidas son fácilmente compilables
para cualquier tipo de arquitectura, existen otras aplicaciones,
como el \emph{kdu\_show}, que son fuertemente dependientes de la
plataforma. Las partes fuertemente dependientes de arquitectura de
una aplicación son la interfaz de usuario, la comunicación por red
y la gestión de hilos concurrentes. Estas partes pueden ser
realizadas en Kakadu con Java, de forma el núcleo de nuestra
aplicación estará escrita en Java, con la portabilidad que eso
conlleva, y seguiremos disponiendo de la potencia de la librería
Kakadu.

Las clases de la biblioteca Kakadu poseen, en sus comentarios,
instrucciones para construir la interfaz Java apropiada. Estas
instrucciones son interpretadas por la aplicación
\emph{kdu\_hyperdoc}, la cual es la encargada de crear las clases
Java.

Todas las macros que existan en el código fuente de Kakadu, son
exportadas a Java como variables ''public final static'' de la
clase \emph{Kdu\_globals}.

Algunas funciones no pueden ser exportadas a Java, como por
ejemplo, la sobrecarga de operadores. Por esta razón la mayoría de
las clases disponen de alternativas para que puedan ser
exportadas.

Cuando se emplean objetos Java que representan objetos nativos, es
preciso tener en cuenta que la memoria de los objetos nativos no
es liberada automáticamente por el recolector de basura. Por ello,
Kakadu incluye en cada clase interfaz Java el método
\emph{Destroy}, cuya misión es destruir el objeto nativo al cual
representa.

Existen varias formas para exportar los elementos nativos a Java.
Los principales son los siguientes:

\begin{itemize}

\item \emph{Reference}: Es aplicado a las clases, y es el método
más comúnmente usado para exportar las clases a Java.

\item \emph{Interface}: Es aplicado a las clases y es usado en
circunstancias especiales para evitar el uso ineficiente de la
memoria, cuando un objeto C++ es internamente una interfaz de otro
objeto C++ interno. Las clases exportadas de esta forma no
contienen métodos virtuales, no contienen variables y no son
derivadas.

\item \emph{Copy}: Es aplicado a las clases cuyos objetos
resultantes son de tamaño conocido (no están derivadas ni poseen
métodos virtuales) y pueden ser fácilmente pasadas por valor a
cualquier función.

\item \emph{Callback}: Por defecto, y a menos que se indique lo
contrario, todos los métodos de una clase exportada con
\emph{Reference} son exportados a Java. Estos métodos sin embargo
poseen una debilidad, y es que si la clase a los que pertenecen es
derivada en Java, y alguno de los métodos es sobrecargado con un
método nuevo escrito en Java, si algún otro método nativo hacía
uso de dicho método, no llamará a la nueva versión, como ocurre
normalmente con la sobrecarga de métodos (en Java, para todos los
métodos, y en C++, sólo para los métodos virtuales), sino que
seguirá llamando a la versión nativa original. Esto se puede
solucionar exportando el método que queramos como \emph{Callback}.
De esta forma, el código nativo podrá llamar a los métodos
sobrecargados en Java. De momento, Kakadu establece una serie de
restricciones con este tipo de exportación a métodos que acepten
únicamente tipos de datos básicos y devuelvan un tipo de dato
básico, sin admitirse \emph{arrays}. El uso de métodos
\emph{Callback} produce una sobrecarga de código y complejidad en
la interfaz Java.

\end{itemize}

Las clases Java de Kakadu son agrupadas en el paquete
\emph{kdu\_jni}. Cualquier aplicación Java que haga uso de estas
clases necesitará para su correcto funcionamiento las librerías de
enlace dinámico \emph{jni\_source} y la correspondiente al sistema
base. En el caso de \emph{Windows}, y la versión 4.0 de Kakadu,
estas librerías son \emph{jni\_source.dll} y, o bien
\emph{kdu\_v40R.dll} para la versión \emph{Release}, o bien
\emph{kdu\_v40D.dll} para la versión \emph{Debug}.
