Volver a la wiki

ADR: Detección de EMF incrustado en stencils Visio + conversión con fallback

Fecha

2026-07-13

Estado

Implementado (v1.54.1)

Problema

Regresión del import Visio: los stencils de Cisco (Catalyst 9000) no se renderizan tras la importación. Causa: Cisco incrusta el arte en formato EMF (Enhanced Metafile, nativo de Windows), y libvisio-ng lo envuelve en un <image href="data:image/emf"> que los navegadores web no saben pintar. Del fichero real de Catalyst 9000 (40 MB), 165/165 masters son solo-EMF. Reporte en PROD por Edu el 2026-07-13.

Impacto UX: miniaturas rotas en el modal de stenciles, stencil en el editor muestra icono de imagen rota.

Opciones consideradas

1. Renderizar EMF en el navegador (rechazado)

2. Mostrar placeholder en lugar del master (rechazado)

3. Conversión EMF → PNG en el servidor [ELEGIDA]

Detectar automáticamente stencils solo-EMF y convertirlos a PNG durante el import. Ventajas:

Decisión

Detección

Función svg_is_emf_only(svg_text):

Conversión con dos capas

Lote 1: EMF → SVG vectorial (alta calidad)

Rasterizado: SVG → PNG (2400 px)

Lote 2: EMF → PNG directo (fallback, menor calidad)

Postproceso

Desaprobación

Rationale

  1. Tres pasos de conversión (EMF→SVG→PNG + fallback):

    • Maximiza calidad (SVG→PNG es sin pérdida de geometría).
    • Cubre fallidos (EMF→PNG directo nunca falla, aunque con menor resolución).
    • No usa timeouts infinitos (120 s por rsvg, 600 s total).
  2. Un lote por operación:

    • LibreOffice: arranque una sola vez (costo amortizado entre 165 masters).
    • Sin profiler/paralelización: secuencial, pero tolerable (<2 min).
  3. Postproceso en C (Pillow):

    • Versión anterior usaba loop por píxel; QA PR 3 descubrió OOM con shapes altos (1+ MB de píxeles).
    • ImageChops opera en C, sin materializar buffers intermedios.
  4. Desaprobación vs. reintento:

    • Una conversión que falla probablemente indica corrupción de datos o timeout.
    • Reintentar no aporta: o hay bug (reintento infinito) o es una excepción genuina.
    • Descartar = operación atomica, no ambigua.
  5. Memoria en dev (512M → 1024M):

    • libvisio_ng pica ~515 MB de RSS.
    • Kernel OOM-killaba con 512M (además, el techo ya mordía a mypy, AUDIT s215).
    • PROD no limita; dev sigue siendo aislado.

Alternativas rechazadas

Impacto

Positivo

Negativo

Restricciones futuras

Testing


Véase también

Subir