+ uns sig_size = image_signature_size(sig->len);
+ if (display_base64)
+ {
+ byte buf[BASE64_ENC_LENGTH(sig_size) + 1];
+ uns enc_size = base64_encode(buf, (byte *)sig, sig_size);
+ buf[enc_size] = 0;
+ MSG("base64 encoded: %s", buf);
+ }
+ if (display_base224)
+ {
+ byte buf[BASE224_ENC_LENGTH(sig_size) + 1];
+ uns enc_size = base224_encode(buf, (byte *)sig, sig_size);
+ buf[enc_size] = 0;
+ MSG("base224 encoded: %s", buf);
+ }
+}
+
+static struct image_context ctx;
+static struct image_io io;
+
+static void
+write_segmentation(struct image_sig_data *data, byte *fn)
+{
+ MSG("Writing segmentation to %s", fn);
+
+ struct fastbuf *fb = bopen(fn, O_WRONLY | O_CREAT | O_TRUNC, 4096);
+ struct image *img;
+ TRY(img = image_new(&ctx, data->image->cols, data->image->rows, COLOR_SPACE_RGB, NULL));
+ image_clear(&ctx, img);
+
+ for (uns i = 0; i < data->regions_count; i++)
+ {
+ byte c[3];
+ double luv[3], xyz[3], srgb[3];
+ luv[0] = data->regions[i].a[0] * (4 / 2.55);
+ luv[1] = ((int)data->regions[i].a[1] - 128) * (4 / 2.55);
+ luv[2] = ((int)data->regions[i].a[2] - 128) * (4 / 2.55);
+ luv_to_xyz_exact(xyz, luv);
+ xyz_to_srgb_exact(srgb, xyz);
+ c[0] = CLAMP(srgb[0] * 255, 0, 255);
+ c[1] = CLAMP(srgb[1] * 255, 0, 255);
+ c[2] = CLAMP(srgb[2] * 255, 0, 255);
+ for (struct image_sig_block *block = data->regions[i].blocks; block; block = block->next)
+ {
+ uns x1 = block->x * 4;
+ uns y1 = block->y * 4;
+ uns x2 = MIN(x1 + 4, img->cols);
+ uns y2 = MIN(y1 + 4, img->rows);
+ byte *p = img->pixels + x1 * 3 + y1 * img->row_size;
+ for (uns y = y1; y < y2; y++, p += img->row_size)
+ {
+ byte *p2 = p;
+ for (uns x = x1; x < x2; x++, p2 += 3)
+ {
+ p2[0] = c[0];
+ p2[1] = c[1];
+ p2[2] = c[2];
+ }
+ }
+ }
+ }
+
+ io.fastbuf = fb;
+ io.image = img;
+ io.format = image_file_name_to_format(fn);
+ TRY(image_io_write(&io));
+ image_io_reset(&io);
+
+ image_destroy(img);
+ bclose(fb);