Trabajo Práctico 1
Fecha de entrega: Domingo 7 de marzo
Introducción
Objetivo
El objetivo del presente trabajo práctico es la implementación de un software de terminal para el procesamiento de imágenes.
El trabajo consiste en la resolución de un problema mediante el diseño y uso de TDAs y en la reutilización de los tipos desarrollados a lo largo del curso en trabajos anteriores.
Alcances
Mediante el presente TP se busca que el estudiante adquiera y aplique conocimientos sobre los siguientes temas:
Encapsulamiento en TDAs,
Punteros a funciones,
Archivos,
CLA,
Modularización,
Técnicas de abstracción,
además de los temas ya evaluados en trabajos anteriores.
Trabajo
El enunciado de este trabajo será breve, no se introducirá ningún concepto
nuevo. Ya tenemos implementado nuestro TDA pixel_t
, imagen_t
, ya conocemos
los formatos PPM y BMP, ya resolvimos problemas donde nos pidieron implementar
funciones y módulos con interfases ya previamente diseñadas. También tenemos
como ejemplos los códigos de prueba dados.
En este trabajo se planteará un problema, y el alumno deberá resolverlo con las herramientas ya adquiridas, deberá extender de forma consistente los TDAs y módulos ya desarrollados y deberá diseñar los TDAs que el problema requiera. Se evaluará además el correcto uso de los TDAs respetando la abstracción y el "modelo" de Alan-Bárbara.
Requerimientos
Se quiere tener una aplicación que pueda realizar transformaciones arbitrarias de archivos PPM y BMP. Por ejemplo, si se ejecutara:
$ ./20202_tp1 -input gatito.bmp -filter brillo -20 -filter sepia -output gatito_oscuro_sepia.bmp
el programa deberá abrir como entrada (-input
) el archivo gatito.bmp
y deberá
aplicar en ese orden los filtros (-filter
) de brillo con parámetro -20
y luego
el filtro sepia, el resultado de las operaciones se guardará (-output
) como el
archivo gatito_oscuro_sepia.bmp
.
En todas las operaciones hay involucrado un archivo de entrada y un archivo de
salida, que a su vez puede ser BMP o PPM. La extensión del archivo determinará
si se trata de uno o del otro. Además puede no especificarse la entrada o no
especificarse la salida, en esos casos se asumirá que se lee un PPM por stdin
o que se escribe un PPM por stdout
respectivamente.
El orden de los parámetros no importa, más allá del orden relativo de los
filtros que deben ser aplicados en la secuencia que se defina. Es decir, si
bien siempre después de -input
debe estar el nombre del archivo de entrada, nadie
dice que -input
(de venir) tenga que estar en argv[1]
, el par
-input
+ nombredearchivo puede estar en cualquier ubicación.
La aplicación permitirá aplicar los filtros (-filter
) del EJ4 pero también las
operaciones de recorte (-crop
) del EJ3 y de espejado horizontal (-horizontal
) del EJ2.
A continuación todas las opciones del programa:
Flag |
Significado |
Parámetros |
Ejemplos |
---|---|---|---|
|
Archivo de entrada |
1: Nombre de archivo |
|
|
Archivo de salida |
1: Nombre de archivo |
|
|
Filtro |
2 o 3: Nombre de filtro y parámetros |
|
|
Recorte |
1: Área de recorte (ver después) |
|
|
Espejado horizontal |
0 |
|
|
Espejado vertical |
0 |
|
Los parámetros de recorte son WxH+X+Y
donde W
es ancho, H
alto, X
el
x0
e Y
el y0
(ver imagen_recortar
del EJ3). En el ejemplo de la tabla
se recorta un recuadro de 100x150 pixeles partiendo del \((20, 30)\).
Algunos ejemplos de invocación:
Lee un PPM de stdin
, le aplica el filtro valencia y lo vuelca como PPM en
stdout
:
$ ./20202_tp1 -filter valencia < gatito.ppm > gatito_valencia.ppm
Lee como entrada el BMP gatito.bmp
, lo espeja horizontalmente, recorta un área
de 100x100 pixeles en la esquina superior izquierda, lo espeja de vuelta, lo
guarda como un PPM gatito.ppm
. El resultado de la serie de operaciones es una
imagen de 100x100 equivalente a haber recortado la esquina superior derecha de
la imagen original.:
$ ./20202_tp1 -input gatito.bmp -horizontal -crop 100x100+0+0 -horizontal -output gatito.ppm
Lee como entrada el PPM gatito.ppm
, le aplica una mezcla con el color magenta
(0xFF00FF
), invierte los colores, le aplica el filtro toaster y lo guarda
como el BMP gatito.bmp
:
$ ./20202tp1 -filter mezclar magenta -filter invertir -output gatito.bmp -input gatito.ppm -filter toaster
Lee como entrada un PPM de stdin
y lo escribe como PPM por stdout
:
$ ./20202tp1
Algunos ejemplos (no extensivos) de invocación incorrecta:
Opción inválida:
$ ./20202tp1 -banana
$ ./20202tp1 banana
Falta nombre de archivo:
$ ./20202tp1 -input
Filtro inválido:
$ ./20202tp1 -filter difuminado
Parámetros incorrectos en el filtro:
$ ./20202tp1 -filter monocromo
Esto no va:
Color inexistente $ ./20202tp1 -filter mezclar mostaza
Parámetros inválidos de recorte:
$ ./20202tp1 -crop 6x6+8
Nota
Se incluyen estos ejemplos para dar un panorama de qué cosas hay que mirar, hay otras invocaciones inválidas no incluídas acá.
Nota
Si bien tanto -input
como -output
deberían ser únicos, no hace falta que
se considere como error la repetición. Bien puede optarse por quedarse con
la primera, la última o alguna de las ocurrencias. Tampoco estaría mal si se
considerara como un error. Se deja a criterio del alumno.
Diseño
En cualquier aplicación se distinguen tres etapas bien definidas:
Entrada y validación
Procesamiento
Salida
Debe respetarse este esquema. Es decir, el procesamiento de todos los argumentos
debe hacerse en la etapa 1. ¿Qué significa procesar?, procesar significa
convertir todas esas cadenas de caracteres a entidades que tengan sentido dentro
de la aplicación, como enumerativos, punteros, punteros a funciones, instancias
de TDAs, y al realizar ese procesamiento además deben validarse. Dicho por la
negativa, si al momento de hacer una mezcla se tiene todavía una cadena que
diga "magenta"
y no un pixel_t
con la representación de ese color (o en su
defecto el entero 0xFF00FF
) o si todavía se tiene la cadena "mezclar"
y no
un puntero a función a filtro_mezclar
(o en su defecto a algún enumerativo
que identifique esta función) el trabajo práctico está mal.
El trabajo práctico es de TDAs. Debe implementarse un TDA para resolver la funcionalidad de procesamiento de argumentos. El paso de entrada en algún momento generará un vector de operaciones que se aplicarán en el procesamiento. Ese vector deberá ser también un TDA. El no uso de TDAs para resolver estos problemas implicará que el trabajo práctico esté mal.
Nota
El procesamiento de los argumentos de este trabajo es complejo. Es imprescindible que las estructuras y estrategias que se van a implementar se diseñen y prueben primero. Cualquier estrategia de empezar a programar sobre la marcha e ir viendo va a fracasar.
Entrega
Requisitos
Los únicos requisitos son que el programa resuelva correctamente la funcionalidad pedida y que lo haga utilizando TDAs con un diseño planificado a conciencia. Si hacés eso nada puede salir mal.
Entregables
Deberá entregarse:
El código fuente del trabajo debidamente documentado.
El archivo
Makefile
para compilar el proyecto.
Nota
El programa debe:
estar programado en C,
estar completo,
compilar...
sin errores...
sin warnings,
correr...
sin romperse...
sin fugar memoria...
resolviendo el problema pedido...
esto es generando un BMP/PPM válido a un BMP/PPM de entrada.
Trabajos que no cumplan con lo anterior no serán corregidos.
La entrega se realiza a través del sistema de entregas.
El ejercicio es grupal permitiéndose grupos de hasta 2 integrantes.
Si elegís hacer el trabajo en grupo te pedimos que nos avises o por mail o por Discord quién es tu compañero de grupo así lo cargamos en el sistema de entregas. (Si el grupo sufriera alteraciones avisanos también.)