diff options
| author | Ralph Amissah <ralph.amissah@gmail.com> | 2026-08-26 22:44:05 -0400 |
|---|---|---|
| committer | Ralph Amissah <ralph.amissah@gmail.com> | 2026-08-28 10:02:05 -0400 |
| commit | b2aaf09e46d6c7450311c5f684f3d811521b3ad1 (patch) | |
| tree | 8c80691b95e77286fa694af858db39360a7ca01b | |
| parent | .ssp digests: report missing or unreadable image (diff) | |
.ssp digest: add image file's own pixel dimensions
Complete image file digest identity record: add
px:<width>x<height> to the .ssp image record, read from the
image file header (imageformats.read_image_info, no decode):
.image: won_benkler_2_1.png sha256:5BA4...D128 bytes:93861 px:420x342
(The w##h## dimensions in the markup are display dimensions, not the
file's: they are author set, or where given as w0h0 are derived by
_image_dimensions and capped to a maximum display width, and they
become the width/height attributes of the output format image display).
(assisted by Claude-Code)
| -rw-r--r-- | org/ocda_functions.org | 18 | ||||
| -rw-r--r-- | org/ocda_obj_setter.org | 2 | ||||
| -rw-r--r-- | org/out_src_abstraction_ocda_ssp.org | 18 | ||||
| -rw-r--r-- | src/sisudoc/ocda/abstraction/ssp.d | 18 | ||||
| -rw-r--r-- | src/sisudoc/ocda/meta/metadoc_from_src_functions.d | 18 | ||||
| -rw-r--r-- | src/sisudoc/ocda/meta/metadoc_object_setter.d | 3 |
6 files changed, 67 insertions, 10 deletions
diff --git a/org/ocda_functions.org b/org/ocda_functions.org index 4745bc5..71d1b97 100644 --- a/org/ocda_functions.org +++ b/org/ocda_functions.org @@ -3448,6 +3448,24 @@ SHA_256_Hashes_ obj_digest(M)( writeln("WARNING, image not found or unreadable: ", filename, "\n ", file_with_path); } + /+ ↓ the image file's own pixel dimensions, which are not the display + dimensions carried by the markup (w##h##): those are author set, or + where given as w0h0 are derived by _image_dimensions and capped to + a maximum display width. Header read only, no decode. + +/ + if (!_file_info.fileMissing) { + import imageformats; + int _w, _h, _chans; + try { + read_image_info(file_with_path, _w, _h, _chans); + _file_info.imageWidth = _w; + _file_info.imageHeight = _h; + } catch (Exception ex) { + debug(images) { + writeln("image dimensions not read: ", filename); + } + } + } return _file_info; } obj.metainfo.sha256.text = obj.text.sha256Of; diff --git a/org/ocda_obj_setter.org b/org/ocda_obj_setter.org index 8e7a67c..f16e133 100644 --- a/org/ocda_obj_setter.org +++ b/org/ocda_obj_setter.org @@ -54,6 +54,8 @@ struct ST_file_name_hash_size_ { ubyte[32] fileHash_sha256; ulong fileSize; bool fileMissing = false; // file not found or unreadable, fileHash_sha256 & fileSize unset + int imageWidth = 0; // actual pixel dimensions of the + int imageHeight = 0; // file, not the display dimensions carried in the markup (w##h##) } struct SHA_256_Hashes_ { char[] summary; diff --git a/org/out_src_abstraction_ocda_ssp.org b/org/out_src_abstraction_ocda_ssp.org index d2bb8a4..64af5cc 100644 --- a/org/out_src_abstraction_ocda_ssp.org +++ b/org/out_src_abstraction_ocda_ssp.org @@ -268,10 +268,13 @@ template spineAbstractionTxt() { } } /+ ↓ images, repeatable record, one per image in order of appearance: - .image: <filename> sha256:<HEX> bytes:<n> - filename first (the object's handle on the image), remaining fields - self-describing key:value tokens so that further fields (e.g. dim:) - can be added later without invalidating existing readers + .image: <filename> sha256:<HEX> bytes:<n> px:<width>x<height> + .image: <filename> missing:true + filename first (the object's handle on the image), remaining fields + self-describing key:value tokens so that further fields can be + added later without invalidating existing readers. px: is the + file's own pixel size, not the display dimensions (w##h##) which + the object text already carries +/ if (obj.metainfo.sha256.images.length > 0) { foreach (i; obj.metainfo.sha256.images) { @@ -280,7 +283,12 @@ template spineAbstractionTxt() { ~ " missing:true" : ".image: " ~ i.fileName ~ " sha256:" ~ i.fileHash_sha256.toHexString.to!string - ~ " bytes:" ~ i.fileSize.to!string; + ~ " sha256:" ~ i.fileHash_sha256.toHexString.to!string + ~ " bytes:" ~ i.fileSize.to!string + ~ ((i.imageWidth > 0 && i.imageHeight > 0) + ? " px:" ~ i.imageWidth.to!string + ~ "x" ~ i.imageHeight.to!string + : ""); } } /+ ↓ text attributes +/ diff --git a/src/sisudoc/ocda/abstraction/ssp.d b/src/sisudoc/ocda/abstraction/ssp.d index ea76d71..25cc467 100644 --- a/src/sisudoc/ocda/abstraction/ssp.d +++ b/src/sisudoc/ocda/abstraction/ssp.d @@ -286,10 +286,13 @@ template spineAbstractionTxt() { } } /+ ↓ images, repeatable record, one per image in order of appearance: - .image: <filename> sha256:<HEX> bytes:<n> - filename first (the object's handle on the image), remaining fields - self-describing key:value tokens so that further fields (e.g. dim:) - can be added later without invalidating existing readers + .image: <filename> sha256:<HEX> bytes:<n> px:<width>x<height> + .image: <filename> missing:true + filename first (the object's handle on the image), remaining fields + self-describing key:value tokens so that further fields can be + added later without invalidating existing readers. px: is the + file's own pixel size, not the display dimensions (w##h##) which + the object text already carries +/ if (obj.metainfo.sha256.images.length > 0) { foreach (i; obj.metainfo.sha256.images) { @@ -298,7 +301,12 @@ template spineAbstractionTxt() { ~ " missing:true" : ".image: " ~ i.fileName ~ " sha256:" ~ i.fileHash_sha256.toHexString.to!string - ~ " bytes:" ~ i.fileSize.to!string; + ~ " sha256:" ~ i.fileHash_sha256.toHexString.to!string + ~ " bytes:" ~ i.fileSize.to!string + ~ ((i.imageWidth > 0 && i.imageHeight > 0) + ? " px:" ~ i.imageWidth.to!string + ~ "x" ~ i.imageHeight.to!string + : ""); } } /+ ↓ text attributes +/ diff --git a/src/sisudoc/ocda/meta/metadoc_from_src_functions.d b/src/sisudoc/ocda/meta/metadoc_from_src_functions.d index 6e4aec3..6a000ea 100644 --- a/src/sisudoc/ocda/meta/metadoc_from_src_functions.d +++ b/src/sisudoc/ocda/meta/metadoc_from_src_functions.d @@ -3208,6 +3208,24 @@ template docAbstractionFunctions() { writeln("WARNING, image not found or unreadable: ", filename, "\n ", file_with_path); } + /+ ↓ the image file's own pixel dimensions, which are not the display + dimensions carried by the markup (w##h##): those are author set, or + where given as w0h0 are derived by _image_dimensions and capped to + a maximum display width. Header read only, no decode. + +/ + if (!_file_info.fileMissing) { + import imageformats; + int _w, _h, _chans; + try { + read_image_info(file_with_path, _w, _h, _chans); + _file_info.imageWidth = _w; + _file_info.imageHeight = _h; + } catch (Exception ex) { + debug(images) { + writeln("image dimensions not read: ", filename); + } + } + } return _file_info; } obj.metainfo.sha256.text = obj.text.sha256Of; diff --git a/src/sisudoc/ocda/meta/metadoc_object_setter.d b/src/sisudoc/ocda/meta/metadoc_object_setter.d index 7abde64..a88f491 100644 --- a/src/sisudoc/ocda/meta/metadoc_object_setter.d +++ b/src/sisudoc/ocda/meta/metadoc_object_setter.d @@ -105,6 +105,9 @@ template ObjectSetter() { string fileName; ubyte[32] fileHash_sha256; ulong fileSize; + bool fileMissing = false; // file not found or unreadable, fileHash_sha256 & fileSize unset + int imageWidth = 0; // actual pixel dimensions of the + int imageHeight = 0; // file, not the display dimensions carried in the markup (w##h##) } struct SHA_256_Hashes_ { char[] summary; |
