# Laboratorio de la semana 3: marcos en `gdb` y filtros de imágenes

Los comandos se corren desde `code/week-03`. Las ideas están en los apuntes, en la sección
"El laboratorio, paso a paso".

| Archivo | Qué es | ¿Lo cambian? |
|---|---|---|
| `frames_calls.c`, `frames_static.c`, `frames_array.c` | Los tres programas de la sesión 1 | No |
| `image.h`, `image.c` | El módulo que carga y guarda imágenes | No |
| `filters.h` | Lo que debe hacer cada filtro | No |
| `filters.c` | Los filtros: `brighten` hecho, los demás por escribir | **Sí** |
| `filter_tests.c` | Sus pruebas con `assert` | **Sí** |
| `filter_demo.c` | Aplica los filtros a `images/sun.pgm` y dibuja el resultado | No |
| `images/` | `tiny.pgm`, de 3 x 2, y `sun.pgm`, de 32 x 16 | No |

```sh
make gdb        # compila los programas de la sesión 1 en build/gdb/, con -g -O0
make lab        # compila filter_tests y filter_demo en build/lab/
make test-lab   # comprueba sus filtros; falla hasta que terminen
```

## Sesión 1

### Parte 1: dibujar y comprobar marcos

Para cada programa: **primero dibujen en papel, sin ejecutar**. Después ábranlo en `gdb`
y comparen con `backtrace`, `frame` e `info locals`. Si el dibujo y `gdb` no coinciden,
averigüen por qué antes de seguir. Una variable que todavía no recibió valor se dibuja
con `?`, y `gdb` les mostrará algo cualquiera.

**`frames_calls.c`**: `gdb build/gdb/frames_calls`.

1. Escriban lo que creen que imprime.
2. Dibujen la pila en la primera parada de `break clamp`.
3. Dibujen la pila en la segunda parada. ¿Qué cambió y qué no? ¿El marco de `clamp` es el
   mismo de la primera parada?
4. ¿Por qué `main` y `final_grade` pueden tener cada una su propio `total`?

**`frames_static.c`**: `gdb build/gdb/frames_static`.

1. Escriban lo que creen que imprime.
2. Con `break 9`, dibujen el marco de `next_ticket` en cada una de las tres paradas.
   Pongan `last` y `STEP` fuera de la pila.
3. Con `break 18`, parados dentro del `for`, ¿cuántas variables `last` tiene `main`? ¿Cuál
   usa `printf`?
4. Para cada `last` de este programa y para `STEP`, llenen una tabla con su alcance y su
   tiempo de vida.

**`frames_array.c`**: `gdb build/gdb/frames_array`.

1. Escriban lo que creen que imprime.
2. Con `break 20`, dibujen los marcos cuando ya terminó el ciclo. El parámetro `values` se
   dibuja como una flecha. ¿A dónde apunta?
3. Con `print values` y `print values[0]@3`, comprueben su flecha. Con `up` y `print data`,
   miren el arreglo original.
4. Con `break 13`, dibujen los marcos justo antes del `return`. ¿Por qué `a` de `main` no
   cambió, si `p` sí?
5. ¿Por qué `double_all` puede cambiar `data`, pero no `n`?

### Parte 2: leer el módulo

Lean `image.h` completo y luego `image.c`. Respondan por escrito, sin ejecutar nada. Las
respuestas salen del código. Las preguntas 1 a 6 son para la sesión. Las demás, si no
alcanza el tiempo, quedan para antes de la sesión 2.

1. ¿Qué devuelve `image_load` si el archivo no existe? ¿Cómo lo detecta quien la llama?
2. `struct image` reserva 64 x 64 píxeles. En una imagen de 3 x 2, ¿cuáles de esos píxeles
   se usan? ¿Qué valor tienen los otros cuando la imagen sale de `image_new`?
3. En `read_number`, ¿qué comentarios se saltan? ¿Qué pasa si aparece una letra?
4. ¿Por qué `read_number` puede devolver -1 sin confundirse con un dato válido?
5. ¿Quién cierra el archivo en `image_load`, y por qué `read_image` puede tener varios
   `return` sin arriesgarse a dejarlo abierto?
6. Cuando `main` llama a `image_is_valid(img)`, ¿cuántos bytes se copian? Mídanlo con
   `print sizeof(img)` en `gdb`, y piensen qué pasa en `image_equal`.
7. ¿Para qué sirve `ungetc` en `read_number`? Piensen en `3#comentario`.
8. ¿Por qué `read_image` no revisa `width`, `height` y `max_value` por su cuenta?
9. ¿Por qué `image_save` revisa también el resultado de `fclose`?
10. ¿En `image_from_values`, por qué el píxel de la fila `y` y columna `x` es
    `values[y * width + x]`?

## Sesión 2

### Parte 3: `invert`, `threshold` y `flip_horizontal`

Escríbanlos en `filters.c`, según `filters.h`, y agreguen sus pruebas en `filter_tests.c`,
con el resultado esperado calculado a mano. `test_brighten` es el modelo.

```sh
make lab && build/lab/filter_tests
```

### Parte 4: `box_blur`

Escríbanlo en `filters.c`, también con pruebas. Los apuntes explican las reglas posibles
para los bordes y cuál usamos aquí. Después respondan por escrito: ¿qué regla habrían
preferido para una foto, y por qué?

Cuando pasen sus pruebas, corran `make test-lab`. Luego miren el resultado:

```sh
build/lab/filter_demo
```
