### OpenACS and Tcl/Tk Conference 2025, July 10-11

- Andreas Kupries
- AKTIVE

- AK Tcl Image Vector Extension
- MIT/BSD Licensed
- Inspired by VIPS
- Mixes C and Tcl via Critcl

### AK Tcl Image Vector Extension

- Inspired by VIPS

- Library for the processing of large images

- Similarities

- Demand-driven: Lazy construction
- Horizontally Threaded Execution

- Differences

- double is the only pixel value type
- Wedded to Tcl, not GNOME (GObject)
- Code Generation, also docs, examples

### AK Tcl Image Vector Extension

- Historical notes

- Begun as experiment with code gen
- Operator specs first translated to

- implementations (C, Tcl)

- Then also documentation, examples

- C, Tcl, Critcl - Each used for their strengths

- C is fast
- Tcl is high-level
- Critcl mixes them easily

### AK Tcl Image Vector Extension

- I/O

- Read/write Channels, Files, Tcl Values
- Currently supported image formats:

- PPM, PGM
- AKTIVE (package's own format)

- PPM/PGM values are the connection to Tk

### AK Tcl Image Vector Extension

    operator op::math1::abs {
        section transform math unary

        note Applies the unary function `abs(I)`.

        input

        simplify for   src/type @self   returns src
        simplify for   constant abs

        state -setup {
        #define IN_GEOM aktive_image_get_geometry (srcs->v[0])
    	aktive_geometry_copy (domain, IN_GEOM);
        }

        pixels {
        #define FETCH aktive_region_fetch_area (srcs->v[0], request)
    	aktive_blit_unary0 (block, dst, fabs, FETCH);
        }
    }

    proc aktive::op::math1::abs {src} {
        ::aktive simplify do \
            src/type op::math1::abs \
            /src
        ::aktive simplify do \
            src/type image::from::value \
            /fold/constant/0 abs
        Iabs $src
    }

    critcl::cproc aktive::op::math1::Iabs {
      Tcl_Interp*  ip
      aktive_image src
    } aktive_image {
      /* src :: keep */
      /* no parameters */
      aktive_image _r = aktive_image_check (ip,
            aktive_op_math1_abs_new (ip, src));
      return _r;
    }

    extern aktive_image
    aktive_op_math1_abs_new (Tcl_Interp* ip, aktive_image src) {
      TRACE_FUNC("", 0);

      static aktive_image_type aktive_op_math1_abs_opspec = {
        .name         = "op::math1::abs"
      , .sz_param     = 0
      , .setup        = (aktive_image_setup)  aktive_op_math1_abs_setup
      , .region_fetch = (aktive_region_fetch) aktive_op_math1_abs_region_fetch
      };

      aktive_image_vector srcs = {
          .c = 1, .v = &src
      };

      aktive_image r = aktive_image_new (&aktive_op_math1_abs_opspec,
                                         NULL, &srcs);
      TRACE_RETURN ("(aktive_image) %p", r);
    }

    static int
    aktive_op_math1_abs_setup (
      aktive_image_info* info
    , Tcl_Obj**          meta
    ) {
      TRACE_FUNC("((aktive_image_info*) %p)", info);
      aktive_image_vector* srcs   = &info->srcs;
      aktive_geometry*     domain = &info->domain;
    #define                state  (info->state)
      // - - -- --- ----- -------- ------------- ----------------

      #define IN_GEOM aktive_image_get_geometry (srcs->v[0])
      aktive_geometry_copy (domain, IN_GEOM);

      // - - -- --- ----- -------- ------------- ----------------
      TRACE_GEOMETRY (domain);
    #undef state
      TRACE_RETURN ("(ok) %d", 1);
    }

    static void
    aktive_op_math1_abs_region_fetch (
      aktive_region_info* info    // Params, inputs, (image) state
    , aktive_rectangle*   request // Area to fetch
    , aktive_rectangle*   dst     // Destination in `block`
    , aktive_block*       block   // Pixel storage
    ) {
      [...]
      aktive_region_vector* srcs    = &info->srcs;
      aktive_geometry*      idomain = info->domain;
      [...]
      // - - -- --- ----- -------- ------------- ----------------

      #define FETCH aktive_region_fetch_area (srcs->v[0], request)
      aktive_blit_unary0 (block, dst, fabs, FETCH);

      // - - -- --- ----- -------- ------------- ----------------
      TRACE_RETURN_VOID;
    }

### AK Tcl Image Vector Extension

Section | Lines | Percent
--- | --- | ---
Runtime | 9617 | 9.42
DSL | 5100 | 5.00
Operators | 15414 | 15.10
Generated | 69504 | 68.08
Doc Source | 2455 | 2.40
Total | 102090 | 100.00

### AK Tcl Image Vector Extension

Demo

The images and graphs seen in the coming slides were all created by AKTIVE

Our task: Given an image containing a document or book page, extract the area of the document or page, and rectify it

A complication: For book pages the image may not only contain the page of interest, but also part of the opposite page