[bug #68049] imread() is slow

"Dmitri A. Sergatskov" <[email protected]>
Newsgroups gmane.comp.gnu.octave.bugs
Message-ID <[email protected]>
Please use the bug tracker to post updates to a bug report.  The mailing list is intended as a read-only notification stream.  Info posted to this mailing list address won't appear in the tracker database where it is most useful.

Follow-up Comment #1, bug #68049 (group octave):

With the attached CSET
(file bug68049_magic_read_fast_20260326_100.cset)
I see a factor ~3.5x speedup:

octave:2>  tic; a = imread("3.jpg"); toc
Elapsed time is 0.155641 seconds.
octave:3> 0.55/0.15
ans = 3.6667


CSET summary:

Optimize __magick_read__.cc (bug #68049).

The original code has performance bottleneck primarily caused by inefficient
memory access patterns in pixel loops iterated col-outer/row-inner. Swap to
row-outer/col-inner so reads from the PixelPacket array are sequential.
Also replace per-pixel floating-point division and octave_int(double)
construction with a lookup table for integral output types.

* magick_read.cc (image_region): Store m_row_inc and m_col_inc as members.
Add row_inc() and col_inc() accessors.

* magick_read.cc (read_indexed_images): Swap loop order to
row-outer/col-inner
with strided writes (dest_idx += nRows). Use col_inc for column stepping
instead of col_shift for backward stepping. Reset img_fvec pointer before
alpha computation since the frame loop now advances it.

* magick_read.cc (read_images): Build a lookup table (LUT) mapping each
Quantum value (0..MaxRGB) to the output pixel type when the output is
integral, MaxRGB <= 65535, and the image has more pixels than LUT entries.
Cast through the primitive integer type (P::val_type) during LUT fill to
bypass the octave_int(double) constructor. Swap all six image-type cases
(Grayscale, GrayscaleMatte, RGB, RGBA, CMYK, CMYKA) from col-outer/row-inner
to row-outer/col-inner with strided writes. Add if constexpr dispatch:
integral types use the LUT path or reciprocal multiplication with
static_cast<prim_type>(lrint(...)); float types use division to preserve
rounding semantics; bool uses division to avoid GCC warning.


Dmitri.
-- 


(file #58407)

    _______________________________________________________

Additional Item Attachment:

Name: bug68049_magic_read_fast_20260326_100.cset Size: 29KiB

<https://file.savannah.gnu.org/file/bug68049_magic_read_fast_20260326_100.cset?file_id=58407>


    AGPL NOTICE

These attachments are served by Savane. You can download the corresponding
source code of Savane at
https://savannah.gnu.org/source/savane-f290f6b25beb8cb99bbe243a6cd2c5fef79ffcde.tar.gz


    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?68049>

_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/
signature.asc (application/pgp-signature, 228 B)
-----BEGIN PGP SIGNATURE-----

iHUEABYIAB0WIQQk97aszIMMAvLLwm6qLAuaBUf3TgUCacXbWgAKCRCqLAuaBUf3
TuDnAP9ScyTO+OSRtcgMMqy4BVUErn0xtPpfKNmGox9/UAvKigEAlpOlvOkPS4Ji
LVbMypiWAwzQlVB7Y+Yo/6X5qOHsggc=
=RD3T
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.