From a0d176aa5575fea8ffcc3039cef519ba34fd0f19 Mon Sep 17 00:00:00 2001 From: "Ayush Jamdar (Non-OVT)" Date: Mon, 14 Jul 2025 14:14:16 -0700 Subject: [PATCH 1/9] Initial commit: raw working files --- imgproc/openexr/ImfToMatlab.cpp | 2 +- imgproc/openexr/ImfToMatlab.h | 2 +- imgproc/openexr/MatlabToImf.h | 4 +- imgproc/openexr/exrinfo.cpp | 185 +++++++++++++++++++++++++ imgproc/openexr/exrinfo.m | 20 +++ imgproc/openexr/exrinfo.mex | Bin 0 -> 47056 bytes imgproc/openexr/exrread.cpp | 200 +++++++++++++++++++++++++++ imgproc/openexr/exrread.m | 34 +++++ imgproc/openexr/exrread.mex | Bin 0 -> 47808 bytes imgproc/openexr/exrreadchannels.mex | Bin 0 -> 47424 bytes imgproc/openexr/exrwrite.cpp | 196 ++++++++++++++++++++++++++ imgproc/openexr/exrwrite.m | 17 +++ imgproc/openexr/exrwrite.mex | Bin 0 -> 54688 bytes imgproc/openexr/exrwritechannels.cpp | 2 +- imgproc/openexr/exrwritechannels.mex | Bin 0 -> 70392 bytes imgproc/openexr/make.m | 69 +++++---- octave-functions/README.md | 2 + octave-functions/insertShape.m | 110 +++++++++++++++ octave-functions/nsidedpoly.m | 22 +++ octave-functions/strings.m | 8 ++ opticalimage/oiSet.m | 2 +- scene/pattern/sceneHDRLights.m | 6 +- sensor/sensorComputeArray.m | 3 +- sensor/sensorCreate.m | 27 ++-- utility/dll70/md5/md5.cpp | 2 +- utility/programming/ieParamFormat.m | 4 +- 26 files changed, 865 insertions(+), 52 deletions(-) create mode 100644 imgproc/openexr/exrinfo.cpp create mode 100644 imgproc/openexr/exrinfo.m create mode 100755 imgproc/openexr/exrinfo.mex create mode 100644 imgproc/openexr/exrread.cpp create mode 100644 imgproc/openexr/exrread.m create mode 100755 imgproc/openexr/exrread.mex create mode 100755 imgproc/openexr/exrreadchannels.mex create mode 100644 imgproc/openexr/exrwrite.cpp create mode 100644 imgproc/openexr/exrwrite.m create mode 100755 imgproc/openexr/exrwrite.mex create mode 100755 imgproc/openexr/exrwritechannels.mex create mode 100644 octave-functions/README.md create mode 100644 octave-functions/insertShape.m create mode 100644 octave-functions/nsidedpoly.m create mode 100644 octave-functions/strings.m diff --git a/imgproc/openexr/ImfToMatlab.cpp b/imgproc/openexr/ImfToMatlab.cpp index cfaa9538..6f44a1d5 100644 --- a/imgproc/openexr/ImfToMatlab.cpp +++ b/imgproc/openexr/ImfToMatlab.cpp @@ -24,7 +24,7 @@ #include #include -#include +// #include #ifdef __clang__ #pragma clang diagnostic push diff --git a/imgproc/openexr/ImfToMatlab.h b/imgproc/openexr/ImfToMatlab.h index 7eaab13f..3f855400 100644 --- a/imgproc/openexr/ImfToMatlab.h +++ b/imgproc/openexr/ImfToMatlab.h @@ -25,7 +25,7 @@ #include -#include +// #include #include diff --git a/imgproc/openexr/MatlabToImf.h b/imgproc/openexr/MatlabToImf.h index 4c7dc503..4fc06bae 100644 --- a/imgproc/openexr/MatlabToImf.h +++ b/imgproc/openexr/MatlabToImf.h @@ -306,10 +306,10 @@ inline void convertData(TargetType * dest, switch(srcType) { case mxDOUBLE_CLASS: - convertData(dest, pa, len); + convertData(dest, pa, len); break; case mxSINGLE_CLASS: - convertData(dest, pa, len); + convertData(dest, pa, len); break; case mxINT8_CLASS: convertData(dest, pa, len); diff --git a/imgproc/openexr/exrinfo.cpp b/imgproc/openexr/exrinfo.cpp new file mode 100644 index 00000000..e3b0e2da --- /dev/null +++ b/imgproc/openexr/exrinfo.cpp @@ -0,0 +1,185 @@ +#if _MSC_VER >= 1600 +# define CHAR16_T wchar_t +#endif + +#include "ImfToMatlab.h" + +#include "mex.h" // ONLY include this, not oct.h + +#ifdef __clang__ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wlong-long" + #pragma clang diagnostic ignored "-Wdeprecated-register" + #pragma clang diagnostic ignored "-Wextra" + #pragma clang diagnostic pop +#endif + +// OpenEXR headers +#include +#include +#include +#include +#include +// #include // Don't include, not needed in 2.5.7 + +// Math + exception handling +#include +#include + +// Local utilities +#include "utilities.h" + +#include +#include +#include + +// Namespaces +using namespace OPENEXR_IMF_NAMESPACE; // Use this for OpenEXR 2.x +using Imath::Box2i; + +// Optionally: +using OpenEXRforMatlab::toMatlab; +using OpenEXRforMatlab::fromArray; + + +namespace +{ + +// Temporaty struct to hold a name and a matlab value +struct Pair +{ + const char * name; + mxArray * value; + + Pair() : name(NULL), value(NULL) {} + + Pair(const char * pName, mxArray * pValue = NULL) : + name(pName), value(pValue) + {} + + bool isValid() const { + return name != NULL && value != NULL; + } +}; + + + +// Create a cell array with only the name of the channels +mxArray * getChannelNames(const ChannelList & channels) +{ + typedef ChannelList::ConstIterator ChannelIterator; + + std::vector channelNames; + for (ChannelIterator it = channels.begin(); it != channels.end(); ++it) + { + mxArray * mStr = mxCreateString(it.name()); + channelNames.push_back(mStr); + } + assert(!channelNames.empty()); + + mxArray * cells = mxCreateCellMatrix(1, channelNames.size()); + for (size_t i = 0; i != channelNames.size(); ++i) { + mxSetCell(cells, i, channelNames[i]); + } + return cells; +} + + + +// Create and populate a containters.Map object with the attributes +mxArray * getAttributesMap(const Header & header) +{ + std::vector attributes; + + // Get the full set of attributes + for (Header::ConstIterator it = header.begin(); it != header.end(); ++it) { + const Attribute & attr = it.attribute(); + if (!Attribute::knownType(attr.typeName())) { + continue; + } + + Pair pair(it.name()); + pair.value = toMatlab(attr); + if (pair.isValid()) { + attributes.push_back(pair); + } + } + assert(!attributes.empty()); + + // Create cell arrays with the attributes' names and values + mxArray * nameCell = mxCreateCellMatrix(1, attributes.size()); + mxArray * valueCell = mxCreateCellMatrix(1, attributes.size()); + for (size_t i = 0; i != attributes.size(); ++i) { + mxSetCell(nameCell, i, mxCreateString(attributes[i].name)); + mxSetCell(valueCell, i, attributes[i].value); + } + + // Create the attributes map + mxArray * mapHandle = NULL; + mxArray * mapArgs[2] = {nameCell, valueCell}; + if (mexCallMATLAB(1, &mapHandle, 2, &mapArgs[0], "containers.Map") != 0) { + mexErrMsgIdAndTxt("OpenEXR:exception", + "Could not create the attribute map."); + return NULL; + } + + return mapHandle; +} + + +} // namespace + + + +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) +{ + /* Check for proper number of arguments */ + if (nrhs != 1) { + mexErrMsgIdAndTxt("OpenEXR:argument", "The filename is required."); + } else if (nlhs > 1) { + mexErrMsgIdAndTxt("OpenEXR:argument", "Too many output arguments."); + } + + char *inputfilePtr = mxArrayToString(prhs[0]); + if (inputfilePtr == NULL) { + mexErrMsgIdAndTxt("OpenEXR:argument", "Invalid filename argument."); + } + // Copy to a string so that the matlab memory may be freed asap + const std::string inputfile(inputfilePtr); + mxFree(inputfilePtr); inputfilePtr = static_cast(0); + + try { + // Open a file, but only read the header + InputFile image(inputfile.c_str()); + const Header & header = image.header(); + + const Box2i & dw = header.dataWindow(); + const int width = dw.max.x - dw.min.x + 1; + const int height = dw.max.y - dw.min.y + 1; + + // List of channel names + mxArray * channelNames = getChannelNames(header.channels()); + + // Attributes map + mxArray * attributesMap = getAttributesMap(header); + + // Size in matlab style (rows by columns) + const int dataSize[] = {height, width}; + mxArray * size = fromArray(dataSize); + + // Build the structure + const char* fields[] = {"channels", "size", "attributes"}; + mxArray *bStruct = mxCreateStructMatrix(1, 1, + sizeof(fields)/sizeof(const char *), &fields[0]); + mxSetField(bStruct, 0, "channels", channelNames); + mxSetField(bStruct, 0, "size", size); + mxSetField(bStruct, 0, "attributes", attributesMap); + + // Assign the result + plhs[0] = bStruct; + } + catch( std::exception &e ) { + mexErrMsgIdAndTxt("OpenEXR:exception", e.what()); + } +} + diff --git a/imgproc/openexr/exrinfo.m b/imgproc/openexr/exrinfo.m new file mode 100644 index 00000000..5b4bfe4d --- /dev/null +++ b/imgproc/openexr/exrinfo.m @@ -0,0 +1,20 @@ +function exrinfo( filename ) +%EXRINFO Read metadata from the header of an OpenEXR image. +% INFO = EXRINFO(FILENAME) reads the header of the given OpenEXR +% file and returns a struct with the following fields: +% channels - a cell array with the names of the image channels. +% size - Matlab-style size of the image: it is an 1x2 matrix +% equivalent to [height, width]. +% attributes - a containters.Map object with the full, raw +% attributes from the file. Note that it will +% only contain those attributes for which a Matlab +% conversion is avaiable. +% +% Note: this implementation uses the ILM IlmImf library version 1.7. +% +% See also CONTAINERS.MAP,EXRREAD,EXRREADCHANNELS + +% Edgar Velazquez-Armendariz (eva5@cs.cornell.edu) +% +% (The help system uses this file, but actually doing something with it +% will employ the mex file). diff --git a/imgproc/openexr/exrinfo.mex b/imgproc/openexr/exrinfo.mex new file mode 100755 index 0000000000000000000000000000000000000000..1ea0567192a5a95f6ed5653948cb41145b71f873 GIT binary patch literal 47056 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 iXyPd|?)9usJA@MT3Pd`K%2a;eZ#c#wfoO#3<^K + Originally based on code by: + Jinwei Gu (2006/02/10) +============================================================================*/ + +#if _MSC_VER >= 1600 +# define CHAR16_T wchar_t +#endif + +#include "ImfToMatlab.h" + +#include +// #include + +#ifdef __clang__ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wlong-long" + #pragma clang diagnostic ignored "-Wdeprecated-register" + #pragma clang diagnostic ignored "-Wextra" + #pragma clang diagnostic pop +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utilities.h" + +#include +#include +#include + +using namespace OPENEXR_IMF_INTERNAL_NAMESPACE; +using Imath::Box2i; + + +namespace +{ + +// Read the RGB pixels using the simplfied interface +void readPixels(float * buffer, RgbaInputFile & file) +{ + const Box2i & dw = file.header().dataWindow(); + const int width = dw.max.x - dw.min.x + 1; + const int height = dw.max.y - dw.min.y + 1; + + Array2D halfPixels(height, width); + const off_t offset = - dw.min.x - dw.min.y * width; + + file.setFrameBuffer(&halfPixels[0][0] + offset, 1, width); + file.readPixels(dw.min.y, dw.max.y); + + // Write into the target buffer + const off_t planeOffset = width * height; + float * r = buffer; + float * g = r + planeOffset; + float * b = g + planeOffset; + const off_t xStride = height; + const off_t yStride = 1; + + // Traverse the image in column-major order. Perhaps it is more + // efficient to copy the data in the same order and then call + // the native Matlab transpose, but this should be decent enough. + for (int h = 0; h < height; ++h) { + const Rgba* scanline = halfPixels[h]; + off_t xOffset = 0; + for (int w = 0; w < width; ++w, xOffset += xStride) { + const Rgba & px = scanline[w]; + const off_t idx = xOffset + h*yStride; + r[idx] = px.r; + g[idx] = px.g; + b[idx] = px.b; + } + } +} + + +// Read the RGB channels using the general interface. This load +// only the R,G,B channels of the image +void readPixels(float * buffer, InputFile & file) +{ + const Box2i & dw = file.header().dataWindow(); + const int width = dw.max.x - dw.min.x + 1; + const int height = dw.max.y - dw.min.y + 1; + + const off_t planeOffset = width * height; + float * r = buffer; + float * g = r + planeOffset; + float * b = g + planeOffset; + + FrameBuffer framebuffer; + + // The "weird" strides are because Matlab uses column-major order + const int xStride = height; + const int yStride = 1; + const off_t offset = - dw.min.x * xStride - dw.min.y * yStride; + + const ChannelList & channelList = file.header().channels(); + const char* channels[] = {"R", "G", "B"}; + float* data[] = {r, g, b}; + for (int i = 0; i < 3; ++i) { + + // Get the appropriate sampling factors + int xSampling = 1, ySampling = 1; + ChannelList::ConstIterator cIt = channelList.find(channels[i]); + if (cIt != channelList.end()) { + xSampling = cIt.channel().xSampling; + ySampling = cIt.channel().ySampling; + } + + // Insert the slice in the framebuffer + framebuffer.insert(channels[i], Slice(FLOAT, (char*)(data[i] + offset), + sizeof(float) * xStride, + sizeof(float) * yStride, + xSampling, ySampling)); + } + + // Finally read the pixels + file.setFrameBuffer(framebuffer); + file.readPixels(dw.min.y, dw.max.y); +} + + +// Main entry point. It returns an mxArray* with the appropriate RGB data +// loaded in the matlab way (column major, planar) +mxArray * readPixels(const char * filename) +{ + // Check if it is a YC file, so that we use the RGBA interface to decode it + InputFile file(filename); + const ChannelList & channels = file.header().channels(); + const bool isYC = channels.findChannel("Y") != NULL || + channels.findChannel("RY") != NULL || + channels.findChannel("BY") != NULL; + + // Allocate the requied space + const Box2i & dw = file.header().dataWindow(); + const mwSize width = dw.max.x - dw.min.x + 1; + const mwSize height = dw.max.y - dw.min.y + 1; + const mwSize dims[] = {height, width, 3}; + mxArray * data = mxCreateNumericArray(3, &dims[0], mxSINGLE_CLASS, mxREAL); + float * buffer = static_cast (mxGetData(data)); + + if (!isYC) { + readPixels(buffer, file); + } else { + OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaInputFile ycFile(filename); + readPixels(buffer, ycFile); + } + + return data; +} + +} // namespace + + +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) +{ + OpenEXRforMatlab::mexEXRInit(); + + /* Check for proper number of arguments */ + if (nrhs != 1) { + mexErrMsgIdAndTxt("OpenEXR:argument", "The filename is required."); + } else if (nlhs > 1) { + mexErrMsgIdAndTxt("OpenEXR:argument", "Too many output arguments."); + } + + char *inputfilePtr = mxArrayToString(prhs[0]); + if (inputfilePtr == NULL) { + mexErrMsgIdAndTxt("OpenEXR:argument", "Invalid filename argument."); + } + // Copy to a string so that the matlab memory may be freed asap + const std::string inputfile(inputfilePtr); + mxFree(inputfilePtr); inputfilePtr = static_cast(0); + + try { + plhs[0] = readPixels(inputfile.c_str()); + } + catch(Iex::BaseExc &e) { + mexErrMsgIdAndTxt("OpenEXR:exception", e.what()); + } +} \ No newline at end of file diff --git a/imgproc/openexr/exrread.m b/imgproc/openexr/exrread.m new file mode 100644 index 00000000..ee6b729f --- /dev/null +++ b/imgproc/openexr/exrread.m @@ -0,0 +1,34 @@ +function hdr = exrread( filename ) +%EXRREAD Read OpenEXR high dynamic range (HDR) image. +% HDR = EXRREAD(FILENAME) reads the high dynamic range image HDR from +% FILENAME, which points to an OpenEXR .exr file. HDR is an m-by-n-by-3 RGB +% array in the range (-65504,65504), plus Inf and NaN, and has type single. +% For scene-referred datasets, these values usually are scene illumination +% in radians units. To display these images, use an appropriate +% tone-mapping operator. +% +% Class Support +% ------------- +% The output image HDR is an m-by-n-by-3 image with type single. +% +% Example +% ------- +% hdr = exrread('office.hdr'); +% rgb = tonemap(hdr); +% imshow(rgb); +% +% Note: this implementation uses the ILM IlmImf library version 1.6.1. +% +% Reference: +% Florian Kainz et. al. "The OpenEXR Image File Format". GPU Gems, 2004. +% (http://developer.download.nvidia.com/books/HTML/gpugems/gpugems_ch26.html) +% Industrial Light & Magic OpenEXR website and documentation +% (http://www.openexr.com) +% +% See also EXRWRITE,TONEMAP + +% Edgar Velazquez-Armendariz (eva5@cs.cornell.edu) +% Based on the originals by Jinwei Gu (jwgu@cs.columbia.edu) +% +% (The help system uses this file, but actually doing something with it +% will employ the mex file). diff --git a/imgproc/openexr/exrread.mex b/imgproc/openexr/exrread.mex new file mode 100755 index 0000000000000000000000000000000000000000..ff209a55323160a28185568778fb6dbad3a0d24c GIT binary patch literal 47808 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 WfYF&_w(?K?fn)3!h(?%M{{I2{A-R75 literal 0 HcmV?d00001 diff --git a/imgproc/openexr/exrreadchannels.mex b/imgproc/openexr/exrreadchannels.mex new file mode 100755 index 0000000000000000000000000000000000000000..aeae8b635331b5ece18cab4942310d9589f0e483 GIT binary patch literal 47424 zcmeIb3w)Ht)j$5^N`ROr2&=K)RvRpM30Vl2pw!$Jo`p?_Bq)M*S#~$cN|H@C&qA;l zu}PG5U7On4TCJ~nd$p}rte2|qi%mdoS{1Nb6|114tWmjH#8!F!-!t>f?rhivY~RoS z^Z9)~KCnA8XU?2CbLPyMGndVCgWWkhGb2M0PnPm^C6Q8;3NxePj{<{WGn71hpQW71 zaI+Ix$HaDB%t0bl3VE99$f0N{PY(|toy*}Ol*_UDR-5I9g=dfAa1qMoa*?(A7M{QQ zuH^7e#*CsoZib>K) zeJA^v;#3xx^`&dyYO`G;6n*?0D!ML3WmPF)btbHOSY8v-W;e5(S!TWvB_+={VRCSh zoIqU2P6nSXCFYp%d1g2cp@z@pW?BSSnGw-ON-h?eQaHhk*C0FxpG(a2G&7{YiBG+h z7SR$Bk-`SVo6Yo<2)+3D@Dcqv1M#onLyw&Y@$V^StO((?X53|lD#A(lOf}P!&F~ut z{boE>;7$Rw05;!*&o;wr%y2Biuj5l@rYSg0icd#e=qZ6~&Acpx=i%ePrv;yh_|UVA z2g*V-EI@d*85e;K5i$W+2!I)0W`?5?&NSo2W_Te&s~H!;nId9_<-^i)a*>=s{46QG z1aS{ObMdLfrve}GG>Qnqd@25)M#q4F7{@1~b;^klPBQ=8GU% z8BZ0ANCi9&Z2YjiQ_b{J3BEvzQ*_j@G$k{K!M=+0NE1dhm*SIw4~@r1`mK2xw_ZnG z%;0W>LSL!>>7nr}9va6@_|W(!9hV;(gNH79Yx~fP`wH$p`wtJ_vH!udcmD3P|{K1m}7(y#Mn zL7MRwp)jfVJUb2l_B3)kBTc_Nh<2rF?|3M9D)<>`_K0 zRcYV{($KjhO~34hJX7h319VcsXQrulD)3Xa>#a27;<+?>dkqX~s(N2b!{>u(`gd^} zKA%e?e>cW;D*i*@Cl&m&GBqOy^!xj1>YbE^&iFKP$V?-*yV8uWU1{vw`ZV}=r|I_=)SF5VyJ0s{!7J0u z3s0x954Wb_ryfpOD*E3`gP#lhRQmY@_)G;4r?C%X(#YYpH2U_fH2w9{G~=!?4gQ`q z_*bQoC;5g}e1<=fH1wCIk=xcZ?L9AzK3|_^yj+t;-=O{}`Shf*!?YH$4sR6F;WYFw zO4IMxr?CUJH1&SYXLcz!?)#d9yh zQvt82<7tft%I!=Kfv+<@7zGi=? z?h7{7R<{P)eU0vAtv;TYI>+VdauWe}tN(f+F7~$8uV_P9*Pu^Z;q&N$prd}?iUzl% z!RE5tZPQ(~uAtA|+8Xen@=jk+cg$TdkLB4{)Rlw3_7F&R0nybS2)4OfU4C%mW^{no zFa=a{q4;TPlIl=d0N~-mmYNc^-hP!js|$_b_yD%rfUbwIf+(G zbu~(*P{%WS1>zAgY9=qmdPrLC(n7<8{{ z3^Xua6|js}0z5nD^C56_R)cZKqstx))^;{Kyp`?V#xC^o;=1XMwkFpU*A(0I=GMS6 zcWYw{y24u>2(=Ss38CE4-VxGg`&)h0Hai3d?O0qlPZUq&PHRDVUyv7$=TFlZbOt2Y z-tKGd9F}dffkVo0LeZx9+P%liFN11%iG?H%%o=Q^UbpVP3K)TvAOaoe^d&WPYD25v zLv5&QaFy5lyL_#Ut2%u4dQV%M-|twYMB&&%@ZaFKA<9G~Q)NeKK_!Y(P8f6%2$Kt_9054tze0SCnq^wd?islHlzD zug`@6MC!-IQw<*Dvf&_8UE8`Ed^%;5hE~H4)K)e+E33E&A=PER;QXc1+Rj?W%~5%}3|kouS8qJqQCIG0bHkudaoMI+1-cw{m=VgZ^m!&bnqZvqfLZUV zc6S?k-Q(^g?xcFY06D)Pcl`1VuB3s(7&wU%fwqpIuagw~Uy>{T{#W_jR7Q z5ZFIK(;=@DV0cf60lPTO-oB#E-Em@$fIEGjZ&fu+#YrKTJN@mx`9Ydoz=yCaFd`w3 z9=9woCA0m$Rxh^_^}!RgNYb7eoW_(XTyef|!LqV{vmk1OU{5UCgrb|QqQ;Xd2$h^% zAM~y8`&MGCH2Y4Xt_IhP1yC+BfhU9g#l5BzHaFob{u|R8bIQn}I$1Dg zuB+U^c6pi6>R)EAU`jdzB~vCV0KkKh5;TKTa&kG#Yi;ApkOao{6tz)ir|$J!bP*+| zQL@>CC0abw!{KwPt6ft{N|iZIM^&|Ja!FY{W=ljTmrUj0MT>x3Rx;V9R4-aoS>sTluu< zrPHRAl}>VDz1qIQ#k9610Q~>AVk86XHDsjumubSYl&oPG*+?hDGI73}ppzrTGmw)T zPmjP^8$t5okVGjF<9S&OQ}8en_<0N>u#Okf1`6f>FZP~jo5hMx{ROMA<1|wFD`50c z3!X9aE07-N_hTn@gz~xx`_T`6j2)gFGQ0W**2ee=jqutS)q zd~U*4ZKoaoTqPfe@Wg{Y@pf$OWGiQw=@%bdj-8)OWjxaKh zOnBcg_~|!tygP@%&obft!{Fzc@cV|rC!27kKe=9!F1m-qX?rY#N7=VkfzCm2e)@e9obG9e zXRQPuCx8eam*8~gLp%c#Tt4gHBEjhnig>n3aQQyKD-!%G0vX{h2`=Bs*ek*1`xg5p z_}LPjBNCkM=ER@>;xW=4`3^h>YKF=i$Bc@n%xf}bzJtrGmJ5`2OLFP7k?5`4S_ zpCQ37kl+;({A&_ili(91c)bLlD8Uy=@CzmQQVD*M1aFbx7fbLC34VzL?~>pp5`47; zpCrN8Nbph#-Y3Cr68ugHK3RhIOK{UfvfTS5c$tL1R)UNBQI!3-1efn~4M=eFNP$t? zBEjiwL_FIhxO}JR6$w65AS2u*!Relic=k$gakq)`_Dk?t0vX{E3I25nuH4HLr2m&o z@H`1#A;AkJc%=j{lHgSm+$zDVCHMphUL(OvCAeLJ&ye7=C3uAdpCiFF39d=-dI|23 z;EN>qTnWBZg3puSEfU-*!8;_ld33{ayCis>guhyX*Gup<68s7Y-Y3BqNbox)c!LD* zm*9;O{5}aT?$c5BS_w{f4#o4h1iwlE5e`Uj`5xRB34XPNzfFQKmf){QaJn-mo?R0B z8UaMOSAt(F!S_q>Z%FVX65J)h^ZI#$d=~j`Vxa_|&r!bo{!#*8O5g+%(7Hd!(;_+R z0=P=uJD}(6C8tO0emZXhFKA4Ct5s2q@$cYUJ+}g}Wo@_#*=LNu1x1?rw8*-(M-9WU z{IDJ6BI_y;*CLPBQ!w$U)@$gwhGi1+oRME`1EMqXz$*x9!|&CWf3Dx)3?FesF4wvT z3bpdhy2TNhQ>cY|w*W(nc4Qcqf1onp0Kw`AZytKq8Aj1h49j?4+ZrJ5Jp=0t!ZEgl z?$W|<8kT}PPV!RanyYT~=Kz3=EF zo#FQk%lCkShAaZyu&iSV`xdWuQTBN9%R(br71x4-VYz{F!y63C1w`;Gtm*5l2=z!>9W7_T+OEyI~ziwutU6fHqmsh<(0ND^`x zYgspt6KJ7h(A3_W7!AmI5uPklM(1kwB>t zNH`*{BCU6)+Vc?VbVfYLc}H(@K)nF|Q2(wLS%}CEk$)ZXKh!UDM81P+8jFkeUWc|o zRcj+{g-w%}`Z0sbA@3qB zJQNFpta>iEYc1v|OlK`7$|gtngV-XVfP0aR;dj_i6n5&99pN`)Uqv?T%|cPbKE|(M z*-l8r9$KZ}tA$^RoxuowLlA#WauM7pa{h(NH4VLDQ|pEoYfa;<{$QFYp94x&iVr^h>qKRe4%;exCL?`j&0| zXyxnGo=1=%{cb_1_8!J}WKJGqG!KlbJs(qk17xVJJKBoNBRKEM^ z!X+E{xG>v`!J}=SlZQ-Dhp{eyM(urqCyF4C=P93HFEJRCN8u7 z#OZ{tFzWMSQz1z(!3U*~YesA#f%_8a9G2dD5xOy!$&1kVr8dM)1CY1F*b&>q6PzB6 z;5=go>lg4An}U*w{z||-0#5Xdx8nS0PauOHHQ6#aBh47|lbqpQ&WU@q!6R8(`4+Wj z0gdR3s zmcOxD-nn6>76}!?2014Jc+jUPLu*8T!4t>`-j$FN#Gr+r)zsOqXoGKO4c$V52ff4K z9rHYj%A|gSbZjQ-*H|}`lp!QdowG%Yp7k8Wro?7bZgke3*<|?sg_j`9O)PZP>J&{7BqbK)ul zm9T7O#g5HD1OcUT6Q&NOw)`Wt=P@K}!9cVY#kbXhgN*G%UyaK%T&hKETDSu=Xm|}+ zweCTyvwVyG9WB~b=!{ez(ZVyd$T#T=XCWf?iyST8R7x_>HI4)x#T@6jt!t1q+jaszA8XEx| z(>{>LSN;Y(#EFL-(Yiut&d@nzUsLj{m2c3mWlTyuC-F<8lk@usI5+tnS+hnZe)WgL zhilY7Ic-OqYQoOxM~8lq7>{9?=NhO1hRAyQdX~ls&3I=xA}b4Nzz9Wkcz~t`vWp$z zKw+giW(3*dq}c&npnlr1JYwUQe=57(eRw+5t+a zFZ2`xXd7luZE#OcY>A9t8`Ux@yFbnA{Cef#LG<>Y!Gj$(r6-K3%C0`vSX@}M=88gO zW~x0Qf`zxvR{zvkaI|SQ8hAA31`Pd1Ei<;(MXoswj9+v55u&MnuZHHkaCUKJ_ii+Q zhdumaW%v5LxsmL1V4BXgmp>EyK#OD-$Ib#?O=Ki`DXi8+oVL%Xn?8$u%D@=}9#Ipi zA#ly~&q(iLCCFl(TEjZEX8KVEJ{@2?e1$@=SrfjZaCW4z;4@ zdJO|!aYmkF;dlp~a*I;m`hrzJ~pm+&BDIeYt&fcxA#88;!D^~0)W*4OzmdF zvJBL_S;uC47q+wa6+*v=2@CUbPI)i&xqcehs^@IIP{G-9qo85=7k0U{=so*cC85=5 zRQMiR# z2cln!>V}Ghemab&wQeRsYi;?*dOcf&eu5o1tXsi6l?F(Qlo}R4iLHD?=r1N5EocBO zEV;EvA<4BLl_t{*t<@q4?zb?q;7(&r!vF=Q0K<3mQEK8g zEc21I6bZ+mkwXf+hJIVZmN%zE|K>)|`W&hT{_kmFWU$cKOk_6`6vJnuquYSP`t~Tm zqFtCav$3#wjkXu^weI)xY=;fYKI}|_amHV?w+QO7nSB!hXY|oR(wA`W1O$c+gm{KDa((|0l07re|iLvO6`;4s)Qe zN+Q2v%^lp8sfF+8r*;g!g=p_uih2eCe4I6oDPwFk%9!)0J#t$y2v$aJnm}|Tcd!!J z#9_lX5~X6-DV2|BqsUVTRRY^vE5|@J7~kpnABLkZzV?X<>!=22Ia?YD;2Y=2o7Uhsuw)O!^$&6_z=( zfQ@C+y+|c5lYT_zH?r;swfZ=#treWiVcJnwd$nW8R5LQnw3z#5keM_5Hq4nm!Q4l< zREt()!L*q+Ef8V*Lz_SlW|=&v(BEm@KUVB;h2O&_mtpx8Aw<5j8Zzu69(i%hE3Ej< zELYm?QhTo^PNKe7mWV~}wcH<~wV+{n14jtX$nrdxkRHr5D#oW_c?jnRNcB*&v}glH zATzzT!_9loITZKrB5YoP%5$ya);jV4ONDz$jh*EWP=HO3e}dDfz2CM|8ban^iT#K~ zNb7D|rJhD(qMIolC4)F#Ij(c7qcEZ?@I0bEUbZ^Xy^Y)id!CQn)qEJ=B17lPTHdG)BJMf)R z-&$BTXV}-zX7=ZqHHVqBLVCdFL!_5k9h$>$B3mQO5Z_+4?Z5yqET4cHTGP)594in8 zzmYqLgfo29u=Eni2&WZU*dJ3sis=jHxzpDyTpRlUn0&v1TaL)1#4NgK8-nJ&XQP9l zACSp=YR@Pd3?vYy9M^$#>=RbJhAM%8qTi&&K<7N}SXZO>X-Dd5!gBW+r!U$$y1=Ycndt zN4ht|xy@JV!ugryp9DXOEn<|2pUu53h!aV>?ZenPP#Hc>y4NiQ+^Y62fHibP?BF~~ zRso}wjJX!h*xU61oPmA+q7ukuJHJ}=Q8Jmf9oP?My<}g_g-%d(K_9le;7AyjaX4Iq zz!^BQaCPji!$Q96)}R){@-R;2*p&SiA{fOi{s$c4VFGqWztcZ-y~!u(??+%C`b%8` z{q0NWFNQJc7E|L(*`Br9vz?HmS3-?Xi>vX61PkYKHJ)v%aUIlnlND|#S5KJHHyBeJ zn9YBmcq!kY_SoPPIit(1q_3o`%vJa{8O+BAcVw*#$u90TsciSk#bUN z*z$fa(TdBepKa)=k2P3HFUNr%(@U<2*b!*n+sACQsf;yLVO$yi4pK221CbuC%IG$* zoVW@CgOV68%#S#;vCeR29%1lL!9n+XSYcp+G{_f7>g({=aG2gd(s zNU)_IY)&L;GX4uqQqfs?tUIqm^*Ddyb`Mjn5}WuBcv4UY+9%G4J^Ts!PTJ4BhNby_ zY14ZUpbjcC-SGIUS9rVOEXi#C%X1jPdZ{aAswsrtCA!7N5m*C?SM&7jf zDkg&1`nQOs4Y8Mb=m@_Y8}l{?-NixJyNjJ+g0AJEBmB2mBoX}ph<&h$$Bg0i{63I=t$1l04;%sr)!`dErI@4X3vjMh|S^$tY4vQ)>BK?7#)43b84)?$*fSJ}2!UWtu_;AGhHh0f?DZHSP;d%m)ff|nM;(mi7yYqU5c<8Nm| zwu}WqX^W+%c#&;DotTf^In2^;Ad~Hdv@zRfIa&uL+KMdJxB<$=1_~L+Z==b!ty;vg z6J!O#y`uOZc=4YgFH!tPbU)pa*cUa% zZ*wN}6$?wO_W9D)oLE;8AK}f|7&9y{As$(nXWPowwhSR$7+IJfuFq!W49h%*%`NnA z7~byPe^Kw!>^20!BU`!qmdA!rims zOaY4fFCfvutlX$sw9-MNa0?;PE_0m}-e|6s6C4|sUo)z_Nts~skXmR*qu81{fpBEQA@8)@i&esT0Y@Ka}HjDK&?4qSZ+sI^|9a60uB<)BISwqDREh3Sf-f~6x&rb#c0EINYOS0 zPBfq>;R!ebehf^)Phjmv20Q7(RA%`FgFnRK&TtI)fZooacMB-=kf2cp?M=|Ia`+8^ zI}B{3T!$=X#zr!Bu&ej&;t7UjEP>(H_ufTw?p)@L)j*J4c_Y-Dv%o(a(Uzs?P|cJ5 zJuPD!J7?A+i%1c%l#|4WdpMvbhQy7m!lKw=+AxpKT5~aGTMLh`r1(f4znS8nV^sy5 z8z_E&$Nd!F!{b*|{8b)zQ2aR_pF#0K#QQiq`NP<0lGr)uz(#vftOd1V-s1SQH;*vfXCHoKvf=D_9GNyHvTiM{Qc0&u})A1 z$0JDHAs^+>^krD)NR)p;lxg*1d>_)2(lAqU@jw!C7qqPwjNXqF$dzLr+a-7WKgvifC`dL)qaXipx6pN!67dfaPjC$a;2IPd*Qnx%m2r*OpcNG&JZc5kUPc%ufcp?oS>A{6A{S2} z!IZEnxN(2dPOW?L6d*BE5ia8MKwG|H$z|2^F25akQ&Y*7;(e$AONukv9vNQWvGQNF_Bv_j^8wVUyF3* z#a^J*NTj1syQm|NF^FqxIfmsOhQAP}{+qS(g@xE81sQCR%KHjk;DPNS;LHteS&#jF zvlJF3g*a=W^C~*=*&4f$N)Pux49ih4D7asYvQQs8X^-TV#P)$f(VMVgV$^Jqik^$2 z=tDanG~~6QFDvq5kDw^)Dxqc6V}@moRP-Ih;qVD354XRMY%5Wsordb%hTdZ*&>#w@j`i^zoE*Sg>OjO}0MZwu%DP&3wRN%RZq6V&Ub`|Q_szuAXC3=ILX2(EX zllt;$_{_#R`SV)$yPs(p`@46eZ+`}ATo2Sg=U0XEyES8gT=WC6?;(fFcYS4|eXUe` zv=;S#iuP?IJ&b1mo^Ba+e~UG}>_Tifl^;^OTbXz&6!oe6%s5@O=OQ92gFdDM1OX(%Ia}e`l>c@JJgsic-;IbW3vWhIKMBhmN+6nQ5h226?+IE z)?WuJO#1gG(I1(pY)3)%PZJu!gCfse@lbZ($4w9W0{GdrZyfqE1DwMtTx@XIg|eWpomS&#UOFd;BSf!$C=z}&bz8rY_eaS$FeSLzry`b?OsD|V@4 zDsg-7lh7|=P-uzHo#KcHpIj#wGcfxQyB2wG^Rup{;odB{6rbv$?h zULTr_Y`SB}V+SCHgt_TU<=@PX`#0B}i~bqr-%P#~Fx-zk%eDjK5`r2yq^TEXZ=*$r z@JnK*;lS^RESV<$2eutUr}qi`K?z;oj!l(qxXHX~H|EFg-5G?WZU0Cc`8<){bVyw^ zFa$S&`&WOQ$?N}F!VbQ1jIR;j!cOux7Q^3I{DOK~lDqNu6o#XMwdCg^cN=4UoF$$knB%9BK!&1^VIZ5 zn)FYV=>LPpTvW`z^tV`Px`Oda>yMG~!ziSI?uPO6uUD6B#T2EE$(Oyd!O#myvvHJ- z?If>k_KCeRb;%BO>}f=O>@l9%rJ%^<3BN3Ld(WVO1bLo6Bhge+iew@c$~y|xvB&r%bo|f8by_=C35>)9$>rBC`zexNNAgSd>%fyF!{NT&e=f(L zFgf0X`8`>V>P@#`R1A})Ts_H@4Sovmwv*XW0yWx~1&vjFGO$^Okj=HJlvBk0U|4saae?$0#68drc8$#W5Fv-8!VdM2n{>@4@F>84+V&%`Oz4gqQ;Ql1G-Lkhy zb%j2PErs2Q%aeYZyb3;_X-iH>iuZ zsAHVCQOUNZwug3eYjl|02eC!N`QbKuadw}~)BCZ%0MqoF4$=`a*=@QpW7=&j1%AQ& znQ=q(qpI#7Qx8S+C-4S$-^?1!>^}S(nCpE52a`n%dn^2#+Xeka3HsP9akI(zBkYo+ zIF=f(X@ehOLVh<}%h&`z7V`ky&cKW2K6wQn7i=A7%u z--Wg682AVg%-(ac;;6z(?D^0`Tq@?C(F@F%;PSyfPkn0se{1>^JLtrYLM&B^BbDf2@vV}XQ3mFu$AN) zNE|=Ohr@db*C0OrO#fiGNr1jS0c^4#Z{eVq@qHf^=VOz`1KUe6$HT8-+okdF6C}-j zA*?6UjEAd14)<4yI*b)|S87!vGHWRX!vA;x2eEPgV>`B3#J)7vO;~}Cxh%22!u#TA z_a5A1{T%jIvOL@v#_5Ey%%a_o*RUC|A5oemGZOo*x!lKie>KJ%gxX^I7&OcHp9T#2 z>Zkb#!gs%pjyQyF*@c=k zFGY;dPt@K{NJlGw4%cGIU5c+4@pGX(Q`gp$342yE27!kD8cBHgfmRHEOW?TeD?l4w z!sp{eJH1e?01OXJ!YwqTqHVOy@f|??6>@3#cx65o_Ky6|gKw-7gOCy0j)Z78kmL5I zirNi|tld@AZd8GxjtI3Ik`e8$f@PXZdqisQ64CB*nr8ddr_#0e43>|ncKCd}iUbj# zuXn^&!At<{R34lOwL|J-lty63SVZs`fP7vNzpuqlYS|ChyOQp7wa`t$D<<;a7Ystn zozd3fdi>V49x-om1@1vO!>tJMJ6H|bSO#nWHZGjdF?A2$PTI^+asE01IXH6Du&+di zbOY=b%%v9+{+n30q2Ql^0vgSX25!mVz8DT`*HRL-X7%Ru$~iu@dwQ6v2Y z4z>56WS6_2?!r1vx*HUi53A}YUt@Ll4CuJ5vY3eAzKhzk4VBwI9D0EKCETM0FTj9> z2Xj+Rq|loz`4kbr<=N0Sc6m0ml|f5^)O{phy_tSk+B4W?KE&_-fX;sd85%ug>(h*l&hkC_ z1mt3NGc0E@QK1v&A%fetC=k?a|I_R7vO2^(mno=$pr0E{52D`Cq_u(-aY6! z%lE21`D_J%i}$1qxFAZmeV|z4>OD#`?RxG4w9eSXe${s#iiqDe*#T#|H4e>UN(~us zRVKx~lkFR$)gO*0JX~s`OAYKIel>{>%831Oy|{>eu&|wp2#kRs@dI4O6#v13hiYO_ zsD1_eqcx;o{CALz#q}}vcMszBjs^%wf4kV)yjL0IRgvD~7c;ElxbDvbU4G|`>j7)O zc`?6x6GX;ukpBsdrW@qDsm~rm={4dC`3r#XE9A4xE9C0{`Lh*84a*+ZZXChu#a1S# zrvWhkZq7CIcXM9XFEQ&)^}DD)P;vIVsMkY(*CHsv{z6JUc>?TD)Ihr?zF}By0$yw; zpz-mE%ipmYt7 zAL5wfEmll=0@K6C+wH{Tk6|zcodlW7k0EpI?l_sBCzBZ>GV?hZ8h4|qY;SN@lDtM#{7x+ z-VmE*hRe0k_{xZFP|?Z@TCO4l)#q~_>UyOUl=!Y zCf=olcOgkHiBsCWO3-dUoU?;DsYK#HS%1>WZ5wKm~Z zA9xv%FOFQI)CF{_+v>p!sI0uQ62*KQnYA5R{&rSqrgeO$f5>;YY(*h6ug*Cx!&K=Nnc8b|9YjP zD>%7KSyskAZiT&13-6t4Z+5Lxygqt0mzfB<@k%qi)Xt9=yScj*YJ;NVRY(e6Rb|%R z3eNDJx2{fiTL$iP)A1~sQbKDyibSTz~QK24HfbW zB{1Txb+oqnn%%9{f%X*;1m2gTEaXkJc6!{c?x2;}nrS_MeCPS-dHF4RGp!IH-cE-X z_Mn)xDHv$8wuc~hempNIM2E3{ant+ltls!Lzrdr{#G_Yynf*r8se6c6`z5Fc zGO*I?;IOfxG`9GxojzcA(W7{iU0eZJg8*;tyWU*Xm``GK+$7t6RKA3k5njeY2NX`$;fnUvZ)1RY!P@pj8i8t1rU+^7pnG z#!h@DZ8was;&VDaqwzTen1Rphui&rSylxnmy=E9sBfRES!)V=U822NckMM)P;jhO4 zrx?!M{rF_#hhAQMp2p`9{Qm1l?-<6#dko{3yA0#6_`Htaa9;erVf-&Xf5E!#tRcYg zxfQ=W9EbEZ$iEdIYB7DwAH2a}jwuQR`ztff%)0b`#KsZue#6*;pb+7HgjR%q#meOB z2T)HoJp2a@gMLImw)Bb3#SyHPhcuvgHMsbBOo3sgTFGN zl>Wh>dvEL^SO-2A1D4A{iiWTUp9z3HM~GDgh2PJtDk!=wtE#{n&8{k#aBEIwLFrAo zl?5}pN7NK7&3YuGUfOXCJ+UeYXPZ zGJrqEr)aHV{D$hQEGX>GoKs-UTr;Ymu(BX;&ggIPh;wwN&SUdNXV$PhpcB7zw|@=# zhP_+Wc_Mx@e>y4^zj*OE(OL~!um2HxK>d-b?R8Sy>$5DGDT&P0T~eZC zU645n$}oF0lj~BHulcQEl!M>wAEIo2ZejO`n=)_Bjpp2z{rxQJTPMJ4H=!+v(?dKh z1?+yn8VGPT$(s72X7pn8MG-)&k^cemNft_DL18EBN&GYsNxIEx-E0`_9kWa}HKZ2~ z(u+FMi`gU_JL$!og8q!GCo)nBr*3rSI%L!wqcUikLUPH**l2mtFkT|YnM_bmch=kj zYu2IcQ3XW+K{0AZXD&lxK|x`4L7oFenci2RY(8wz8^@H*bjFKTkIt$~5Yk3xu8k9# z2SPM{)_~40VV7>fQZR{!(quaK5gpD0)UqO81+~SAqIo1w*e-gHZ#MmGDV0to#?zdF zwHcXPQc7p;Xe;O~0=?e*3}Y_!`|0>X0rY$BtvS)`+p@loT-d|AS7&7C<><~QGI9@C zmA_?rH&~V5X6HU@RUXX#>busg53=vc>^U#%p^>j-d}_`5?390G0^zwaxo=pNU1P!N zz2o*}Apf<~a$mG&?V>+hw5I4cgxdd=9~0`fvoMQnJ|`EDPtN&W1|Wa3=Ar=f{X6(E zElwScyDb@`AIQkXAJY3r2Fg>;H3T;@meM<;=g-BP!GE5S`}Sz%PzL=;yR})lL!*^# zS-F6}oi$fcUdle0v2(O?*NEI7<|}vPu5ql9XbA&K=c2HN4y_Lybnjb|3DD((E`bP4!8N|yAIy_fVuy4fp6LQ5?8B6z{&oSTuv9zcc zQ#ng-IgjV#n1H1PAA;`xRk-%9|0_yg()m&X{|`!_KQ+&I$KOor1X|CzFTsn^n|)Ti z3eaksf_L|oUNU*28B1N3pfujIl>=;zA!AvP$W%rvtMRuw=wUuG!n^Syctt5e6@~mV zdT8yDiq8K6PWY>EbA=w7&*|BVPb&OFfD`@(+{Tfgf0*z+!{D@zA$&0}i8AK^o}rws z6!mk6S*>y*gP*DhyDjkPXD38Q%yR;MEyEuZe_xz{(>f^?|Fg9Bpzl-Rv8J%&;@Oj}ulfLM8UP@8^$D~uSghQCmjp)ZFTxsKQ<_9Bs2|9@Q&+F%K z!RI`{Q}O9z_!dPm=VM+i|DB36m$@OhacJ9Enu)Ytz72 zrGfte@KpS4NCV%IhR(-;r{e!KC`KwiX8@iGe_D$Xs~+%F_4cK~ z|3w=3hBS1t;9#brKLhYod{(A`&jUOa|I5?BZ%G4xI1T-$(!if#bn@f=zfhTNY4HEX z@Uf6H`xjzi&-;LuKQiY2de{fj^iAz724z$(tPPNrQg{78@#rmi^I!KpS>O>rifZx?E$ZkVU+kggYJ@2diDJ5P&+$YEb#j~%0WpqVeK=1AJ1H?-P5yR2-uI64OuW-w53W+0f{>BR z8)|D?g(6bQ1x!5&HKhAn{kq>Lgg)oW#dRqfRNCy*>q2eS^$R=gE9}#85=l{X(*FfE zglu25zya1k+h!vk{Ww{_-se>y=EeXQDi^nF_JYbBmNZL-T5@GN(A1fU_S?33;G$z|-|zZK`;J{JzCbyo-x>RtN^ zh-*&WLYG}L>(Oc!n6*rmYw6H~j+*x4R|7??b$R`r9Ra8r2$Md4VO}{AA5Mbndv<)euo*ZFQmtPDIV0np#T5Nn*pBvY=@7 z;zqIwzAo1k*Ocj1G?cqM_B8FDOzocIoL^Pxbj_bVyTRV*YOJhs+DU^LnYJb(V=HUK zH3M&a0-rIeq2gfc|x&4N1=$GF1L$`+2wKTo|cO0MT;t{ z94=eQloPOkrhw-;KD{P>0ptWF>Ka@#7P#q>iMy4_j#UoR%PdvJ9H*nI+BLaka>-N$ zqZK!Tl0YfPW3>%)gU5fOij%uxG7V2Az%QUxljF*9LgRiSZW{FIB=;_x%{E!Sh~x0U zyxA~?V@3nY!`Ig7(}(w8>QO$$*UqMmleHtms$@gz z#PVry*~+TXZdfC~hfUWcRAz%9aPm?rb$gdzN7ED5C}H@gwXgw3gNkWwbI2X^;_e%p z0+R;~IuUcHDdRx1-;-LzZCwpM%qc#2M8pML17FbZQJ5VyhaL?3TGb z%TK;%xWN&co@kS4DrN{*5lupGc{*0bd&@@spJMW}m7z~(lVel`7t9y5FPMiRZL`TB zx#TgEL6aThb-}!*B&6xwU2AM1{}uPB+Tp@L$Q=+M0Iub}RW5#~Dyh`)d8R?1#xH6? z8Nc}OBByq`3kt#bYba-ak(iPum!jEom`^D)Nk*rAW!tb}<87^9(I)9bNjcDtYi3{+ z8(~4K;Wu-QtRy$IF@VY8#Pa~je`+H+CcaKj(9fTc{ zypPev} z{;5V;Dd~N^zYEJayWh`wF>irViDR9`8M^7;(|{COTORkp%xRjDpp_pea!vY5s;z8vR#uV1T;&e7%NoOMobd4kXUCWYFCTVZYTXwf zyi7-ezK&KmRbGc5oyDhN77a!Q}c0#AI!8LuJZ1ozseI|Bgl6&k#b6~j>*W~91(cz3x!Z03V zE&SYC(DVyyA!dE7v}qE@236`ox`4L1PHLFiTn$rznPQk8!-}-H#6lFDG2cgJvu>Ju+7^i}}A zWtJE6S5})jW@sH&V0iuA!^(^MH6pyYRphN4~peisqqzf=IsP?Z1LFgW4TBZqO_ z=UME#!mPg@=gstx9U)sS>KE;z@g;aiH2(CN_oe=fb2j-A^$Hl7>s00EKg2Qi2}Cm- HUjF|BdtXL0 literal 0 HcmV?d00001 diff --git a/imgproc/openexr/exrwrite.cpp b/imgproc/openexr/exrwrite.cpp new file mode 100644 index 00000000..00057e1d --- /dev/null +++ b/imgproc/openexr/exrwrite.cpp @@ -0,0 +1,196 @@ +////////////////////////////////////////////////////////////////////////// +// +// exrwrite.cpp +// +// Matlab interface for writting a float image to exr file +// +// exrwrite(img, filename) +// +// img can be 2d (gray) or 3d (color) hdr image +// +// see also exrread.cpp +// +// Jinwei Gu. 2006/02/10 +// jwgu@cs.columbia.edu +// +// Modified by Edgar Velazquez-Armendariz +// +// +// When using mex to compiling it in matlab, make sure to use VC7.1 or above +// instead of VC6. +////////////////////////////////////////////////////////////////////////// + +#if _MSC_VER >= 1600 +# define CHAR16_T wchar_t +#endif + + +#include +// #include +// #include // Matlab types + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#ifdef __clang__ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wlong-long" + #pragma clang diagnostic ignored "-Wdeprecated-register" + #pragma clang diagnostic ignored "-Wextra" +#endif + +#include +#include +#include +#include +#include +#include +#include +// #include +#include +#include + +#ifdef __clang__ + #pragma clang diagnostic pop +#endif + +#include "utilities.h" +#include "ImfToMatlab.h" +#include "MatlabToImf.h" + + +using namespace OPENEXR_IMF_INTERNAL_NAMESPACE; +using Imath::Box2i; + + + +// Templated function to copy data from either a float or a double array +template +void copyPixels(Rgba *pixels, const T *img, int width, int height, + bool isMonochrome = false) +{ + // Stride to write the same value in all channels when the image + // is monochromatic + const int A = isMonochrome ? 0 : width*height; + + // Copy the pixels + for(int i=0; i(0); + + // Uses matlab's alloc, so that the memory if released when + // the control returns to matlab + Rgba *pixels = (Rgba*)mxCalloc(width*height, sizeof(Rgba)); + + const bool isMonochrome = nd==3 ? false : true; + + // We only know how to write real data, so we cast img to the + // right type, and the template will do the magic, or just + // raise an error + if (mxIsComplex(prhs[0])) { + mexErrMsgIdAndTxt( "OpenEXR:unsupported", + "Matrices of complex data are unsupported." ); + } + void *img = mxGetPr(prhs[0]); + mxClassID category = mxGetClassID(prhs[0]); + switch (category) { + case mxDOUBLE_CLASS: + copyPixels(pixels, (double*)img, width, height, isMonochrome); + break; + case mxSINGLE_CLASS: + copyPixels(pixels, (float*)img, width, height, isMonochrome); + break; + case mxINT8_CLASS: + copyPixels(pixels, (int8_T*)img, width, height, isMonochrome); + break; + case mxINT16_CLASS: + copyPixels(pixels, (int16_T*)img, width, height, isMonochrome); + break; + case mxINT32_CLASS: + copyPixels(pixels, (int32_T*)img, width, height, isMonochrome); + break; + case mxINT64_CLASS: + copyPixels(pixels, (int64_T*)img, width, height, isMonochrome); + break; + case mxUINT8_CLASS: + copyPixels(pixels, (uint8_T*)img, width, height, isMonochrome); + break; + case mxUINT16_CLASS: + copyPixels(pixels, (uint16_T*)img, width, height, isMonochrome); + break; + case mxUINT32_CLASS: + copyPixels(pixels, (uint32_T*)img, width, height, isMonochrome); + break; + case mxUINT64_CLASS: + copyPixels(pixels, (uint64_T*)img, width, height, isMonochrome); + break; + + default: + mexErrMsgIdAndTxt( "OpenEXR:unsupported", + "Matrices of type %s are unsupported.", + mxGetClassName(prhs[0]) ); + } + + try { + RgbaOutputFile file(outputfile.c_str(), width, height, WRITE_RGB); + file.setFrameBuffer(pixels, 1, width); + file.writePixels(height); + } + catch( std::exception &e ) { + mexErrMsgIdAndTxt("OpenEXR:exception", e.what()); + } + + // We don't need to explicitly delete the data because we + // allocated it with mxCalloc + /*delete[] pixels; pixels = NULL;*/ +} \ No newline at end of file diff --git a/imgproc/openexr/exrwrite.m b/imgproc/openexr/exrwrite.m new file mode 100644 index 00000000..f0116b83 --- /dev/null +++ b/imgproc/openexr/exrwrite.m @@ -0,0 +1,17 @@ +function exrwrite( hdr, filename ) +%EXRWRITE Write OpenEXR high dynamic range (HDR) image. +% EXRWRITE(HDR, FILENAME) creates an OpenEXR high dynamic range (HDR) image +% file from HDR, a real numeric high dynamic range image with either one or +% three channels per pixel (i.e. hdr is a m-by-n or m-by-n-by-3 matrix). +% The HDR file with the name filename uses the PIZ wavelet based +% compression to minimize the file size. +% +% Note: this implementation uses the ILM IlmImf library version 1.6.1. +% +% See also EXRREAD,TONEMAP + +% Edgar Velazquez-Armendariz (eva5@cs.cornell.edu) +% Based on the originals by Jinwei Gu (jwgu@cs.columbia.edu) +% +% (The help system uses this file, but actually doing something with it +% will employ the mex file). diff --git a/imgproc/openexr/exrwrite.mex b/imgproc/openexr/exrwrite.mex new file mode 100755 index 0000000000000000000000000000000000000000..9574bfb5999ce3f756e268d1e041a826dcbe994d GIT binary patch literal 54688 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 dv(^zQ5X data(prepareArguments(nrhs, prhs)); + std::unique_ptr data(prepareArguments(nrhs, prhs)); data->writeEXR(); } catch (Iex::BaseExc & e) { diff --git a/imgproc/openexr/exrwritechannels.mex b/imgproc/openexr/exrwritechannels.mex new file mode 100755 index 0000000000000000000000000000000000000000..16aa830b9c920ed5c8f9d8854b732b78882ec7f6 GIT binary patch literal 70392 zcmeFa33yaR);E4T8v#OYP+AeU)(K7`3Tf5^LDP`HZRkLRAPk71Nji%r>6mmwa3jzO za&24VsN?<)<7~`~qs*%!Ixb1r!3A(s6c^kuO$34{21V}oJ5~2~SBGv<-}m|c&-eVf z8gAWFr%s)7>eQ*ddTG96Qk=;o8Be@)r4;^>q+C6syKfkpD`iW`h&fL>m*FNDiKD#t zj^se&Ev4~qqLxU(T>1x3F8eq1&iC?f<1MCR`L*i!J>G}=bGY#q(NCjlV1Lca{*Dp@*m8{Tuwvz~2-dHdBAo zD;q6zVU(gbwZeeztX=)^?*nF%PVr7b{5AONa|%3)j_-lfx5qbq=J$Y+t&l&6!ynmW!s-Q8ani+qxcH1eC2#G; zOMv1mhrlr>E~D|7G~bBSSvf`Q|En??+#2dFfwQ z?US8nUfD8g*+XkP-#nE1eBf~EYv}_zQu+nH-}Cq5H$4Bv2Qw=@JC1Mo*VXgy?|SO| z@$T1;J>Yun36@EWf6jntROfm=K^SoVo^{~XBC=ue08 zqv2l+hZGHe80bfX-yDPf`@oOJ=U-to(csU;!0#6$-%c1?G=3h2Lysoc))@GIjiJxG zV(4K8%HU!uh#t>q(217s`*L(X*Tm4h+*eX#L&++RF-Jvm>ENFcgN7f;u!V!xfu9Q$FSSh7;s+< zekQ^HN7M7B81-dd4F5ALhCbhk!T;sZTeN(;V(9tV81_6K^rPv2WemUcYK->or5N^; z8Uz1C3_f3tVW0QJpl`y!C7K?l#?U8?H!S$;`J~3s!=M;?-XB9QCkRK=rzJ)`>K~*2 z&V&6#Ye%5AsQfRC(O%G4#)7||&&n9|--}@<{}n^t{!o52KC@!*bDY(qzEW<0b7YJ| z-$1=PL+UFv&f@TQNl-ldQ7#t)ZVdb%(BU(fKKn{tI-SQM4?SbR4B@B!gMTN(4(K_H z@!wZkr4P1!`aqh-%V$U_(zs_CTIe6LsWUL!B;|%cEbtH58{syx@#I7aMZva7BlI zj5niW=YZRF`c7TXtFGqo|LAb3xVXI9T~l1|an^Z?i>2bqno5sUT!xoaY%eM(E_Kzp z$}8(VuDYUviB;|zSCMmJm5awkk0~x`a1sG$Rpm`UoI7o%XG}4G4OXjl_(ErWWeIYt ztE?%vm(287ttA!Cx?)eAv(i&$cm((r+tKhQa zhT@Wn8;Z-El~tf!T2;6R@ePyeT*#`pyrH4E)>T*Urp!G{iWg<^{6{Zxm3Z8B_FupX zaWr#Oaelsa4448>RaNd1XsO;+=dn+jF_p#TFPfHv+-tl{Oh{YfuB&!d6<0!SPRh6t zXfwxvN?z^sB4~MT&EjhOJJT~ftGL)xQRiMgwEeg;Pr)4e4;yyR@>t)?M$)U!+s5bFn=2FIP>ek;AN-#g+J);i~smyP#Kl{X`TG z0=Bw3=aM4#Ojd9b$`9=R4;ZR*)mAx6T=~`25S0oL8M&&e5SZ-pO!HPRbk$8S%d4z* z)znwIYw9_?=eL2EU*!U#N5|rHTn)3Gbu|U`<@QorO=(dBY?=(wFoc<&k+sfBl*`mb zIn@mltDN=q_B>Y9BY&i*Defl}^~mCxqlKcLW*t4f)>V@~XGWR3uE6Q3axTpFxTiTi zm5W@k$YQG%z`Dv3SN%0E*na*(Ff{{4LP~*%E<|w!xvOidTn$_oI?KYxG$%?7LjFi@ z`9wLagkM@4vLW1zlNjebk|t4K8z!Qj6xfO!wh8o=Usopj5|#_6jj>mk6^|$$kz?~f(F?tBE3B+-KT_5d_Y=z6Ry=d! zPc7@P<_+`v-xY@#37bz;Q?Ob+?ywSI4%~q9oE~TN3i69MWNv&WnMo|CNpU|xyV=Dv zsT>Ta31$p~C|pE-IqOHVptzrqMON|5;h`+h&{Vq@!ST5oCV6X0Jn%iytCTg1ta{E2 zJ6cP4)#`=<)-DjTVQixnmlKWWL~DL!W!a3W({k+9PWbl`#nzFi=fmw~`T1q2L^+Pi z8rSqXVCJ(bH4(ME&Q(utFFy*o(Y)nBO)ddVBoCKn6zps?t~E8Ts(SMLVb;dLsS_By z5sAXe23J+ll3EuyT`1yNtvaFu9e|!W8$=?ww2mpSaxZjN6;+_6ES>1~){uIHtgTto zy`EaHXHsRA3)vfD=*r4Rrz6bfsF_vpiYGBySW;bGSy{TU2dk6n-~cCh%gS7JJz3?1 zA{iC@|lO7Gb6vD(nD@{A^J!nyTh{} z-sF>tg{k`F#=@Fa&RXD!g|nE|uwF>H*I5UCN^bO4*1t;M10Mcxq1mM*DrR-@Bd z;;bj`gnWJmxk@5NtUWbHz#TKywPd2Z)b*2)1wRQs&}U=AgPFWPYJBS5CDxy!j#3E8 zTjB`;XQHxKx~fVc?zE|fEk+dEDAwy{H5Mb3?BW>ya0?Zv4JAl%642}h3ng$a=(3jCMl_>&T%sthlz zb1kZLEk?^&?)nLN%`DEI0i&nU-A}>(*~89L6AgDjeo4oOx-2vZJhfJ#oKZz+BGFGS zsjI9dnSWBM>>`Yreqx;p+lt^Zf4XJzM9eS#yhK0SlqshX_Fs_G@SkhKJST3xhWDWH zr06@?_!6$;e{KpfXBB?ooIY=U#?i`t6zPAiDpqSa zLpeXrP$_4KdH0ZW@7Zmr=Pyy z4<9-*6taec!-tOI;5l=EJaXu8t2A-W9NPqYv32N(p*fLp5uXB{G_1m1?HV@ynxbLO zCEogqq1QXBOPzJYsxj|Z;;t!mju_^uSyVr)5?#m3tIDc}f#tD04T~OD=5m$Rd)%0f zt8=?O!xnlgtEj{3sVsArcf?CuaT6C%C{ON1n1A66KfVtR$XlM&+hy+bgL8<_*)7#Q(L zVQ^x?UKGObEkMF~{ge>R7!#fs8+&Me+=9QtOO{}AzK;|Dj2;u@_381s_#RMM*-yee z`u#fWzI%R$neQa&_xiVYP$g!zaZm{pF)1Uq>aWm zi%*nx>EE8r-(qS!LHbz#e)FjtFasYa9l$p|#{NrV{=6)Y!*loZw*k-6;Yts;d=a@Hsu;OLX{x9`HMKxYQMyukpR(OAe>y0)2^r0d@;;C?@pm72xq9s3dg=aD6F( z#dZmBC@A!F3vhj@g2x@;FM?soA@n2*a6@+#nI^zdz@cZL0Phom!j=R$3OMv+2=J5; z6#EAScs~K2Ex@tV8hUaCIF{T(k0QXyrj4gifQ#!}a|F1!&bL5->!!v?RS0l#?`Ew4 zHyfGa-5|ily_}5#T-NpY(MxVXP^jR2>; zXvVWnfYUxt<7pM(76XX)76E>d0N)|NFBagt1^BN7_+9~?F2Fkk_+SCvCBQEc;N1fJ z*8*HR$Un&bGX!|D0M8WQX#)IG0X|TG4-w!N0e+bP&k*333-BxfK2(5b3-DnAJXe5c z32;S#TLpNb03R;E=Lql-0(^l0r@gwyQz5`d89=;i1^8$I-XOqfzozjt3UG0M?n(ik zV<6+*BEV^Xvhh49z>Ph)6t_x%i~B}b3-Iv<5xmz3@GAxQIsq>3V{aAUxdQ$c0d5oE zI|TRy0lr&+PZZ#L1-RaHvDgj)o-g2c3Ghh*yjy@z7U0q${z3My2=HV9t}ivS*faq? zMZg~@z^4juivV{B@C*T7Ai%Q(_%s2YEx@M>@LU02D8Ll~t}ltR*g^q5L%^RSz-J2Z z1p>TCfL93cYXo?$0N0oLS!{y_u@Rb7G*eg%bEdt!wUrz7`1^BfD(4SQT ze7*t1d$j<+PJpiw;NpJ&bpm{WfZr;>odSG|0ADD;cL?wj0lr&+mkRK`0^B9QI|O){ z0PhmuTUUhG)4|gkIIV%x8aS+jX|$`Rf(` zODn;SW_}Eb?Ea+{cK_lACG&*Rta*|&^B6!2{O&mg{_?_toX}6?893L+}fy_Uu6n{ z*1CfmnS?h0&>7IoeipG_GtZ^`BADfcbv@vkxfE!c`GS8C&SNd0V9)u`BcsUdzD*gL zxtgeb8JQfizRpr*@GR`=+nV`ngrV4M$gOa><)(gMUo*c4+QB%4$bOO`KQJBs()0|) zUzKjL=X@zQwWF*R|E&-ypJ_Z58R`mulsNNkv~<4xG8vje_OlW&hx&zPeuJ@{mtGMn zeccf6V*C-_%V|cc87Cu;WLE10au{vMNoaEO3PuA4KAO?ZBDxlX?stEOd_#2kEQ;Tg zo)xyN4-l!qd`{xB-hsMIDf?_`Z`DPf+|xh;yi&$>%9KTBFs^YI5?k&upHnxekvAh$CJ0vMD# z|D>7g@Le`kzOV^$;l7F4wrgy&Y(=wXg3}B|g|~xKkeePSC&KEzKX)MG8`_eaDs*tN z!(ThFp!ulWGy;$U|84j{s$Tf8`-=xE&3ojge}TNiUxJv=JY{wmJHQ7#w<-Qv2<$TA zuSfg=&!u+%t;nV*ePGA+&@9|!fxkNKv@Etz61YB+$dbrd}>hH{UHk`}y-%AaQX5NGR9Ddgv#XrB$ zp7Xxv@-m&DE0n-Q!`mUinwKYuIp6vWAbLNb6r{5>&{_abrDT4nneXJ}auJzL8old!(91UHDF(f9gdw=zvymCAWQw*)8+-v`Ilo4|vlZFZ!#^{5EWq=AV5jO0dCs%LN1}R?Ktxs>{2b79Iaog7>e=%1@~h$bWt<|v$+7c8 z36onKsQ4Fy#m!14v@npNbAPcu%o~^cdDuEV@sXay!4>3CJCw}bFtS7?XN%mF7!Ut| zwpBf@sNdK#KXT-B%1yt4cUA)9;JZ*I(BY7&=Y`s$$<0qAD&Kmv!1S%+A8rp!PD2mE zuEJ4HNLEZ;irU_B=XaS3-oUz^2| zb3krdMtq~)FQB$x-PU=LUO&{~ia$$H>(Yp4hdKqkwj+`^KB3FotC%qY~tJVw0bm8ey%9%L|L9%H0DI-A6x912OOqgnO&~gRHn!^ zTg&9Cwy=@Pnbh;st6qNyQzp9!f`%d4Cih1})3!I!Vd}D@VFRNP&WOulQ@_$)pXR?d zt$Uh!?b+R=+vS%+5x#xh`PNYFxSd-62@xPjBuaTnThzN-5&*cZ`AthY~U7o~T^ zA-$s)Pw#{0W9eJ-)i#^273l}`nWheqZ8=>?UyA5ZdT7riFK50oWT_~9MV_=pQQzQY z)%HbVa4Hhz`QxA;wO5`$Z}{;%HE+yuD&pY!A1Eq~qR!6q7iA%;Xv}ez4O3^{a8hU9 zm=g^9eqbx>xGiXKt(%e6X5N58SEy3Ky@U}Mzp$R#w&SbFY&UD>M-V`R>P6oZ4bL}! zpvdya$$UKN$>@(NZTk{6a{%zpeToW4zMLXy)bR%dLh^=cA@6@2L90F|qW_`L*x^ZJ zW>Ysbp+(;ggK-4VY1@>So`n$lr08TiR1e;p^U^aA4Ne9lUq#)>`T$#DSd8T~P$BC^ zw;^afYFAs?=%$^aqMN#mMcLJigvpbk?Grms4-9i?_`VzPyrL|FK@ z9+~Vbi?;}mG9r2DN~j+sHyNZnXy%6~QNTg^V6}j%HTpo!s)P>jWx%HX z9#cdwqD6{ukRn*q4sB@W=Rkq!WD!F!RIv^OqN?JRZ+=V__b?)0#jb6(!%a4!a{}^E zqeDFbF+;`0N)r4-3yi%AB((FwYj(gggTIBb>wYWW`dN_blTqK$WB#<3*c*QYFS3-k(y`SeFT)1PMkir9xCgiGG@YxI+tQ0qJ2LmgnM-F_09_gz*k?f|{A7Tat^-Ko5w z*T-IBXV>9hiZ*;0hK@>R2b!n^C1;1+G>e%5y6``s7q4XQcjWvaHzg4;FcL$JP4aT; z*DC1xHm3o4M0Q_f-Gesj`80s#{ug6F=gD%YA5$X)MPvri4xwKLygu+naFXq5a(@M_ zO`Eq<@wKHDCVC@sS+8-(EfOO4#8Rg}7pl|LU01}%N z69zNxbCiGrHqT3=;c4?wvY8_ML*owk)4KmwUN#hp)<;o~z{jDH|1_cV@sR851zjof zWEM*?D`8SN-3DLM8&ex6`70VSVZ8J`{1pmZ7%yd$4PNkwB*9rVzYZOj$%k6OzPgbb zCyQo21LW{+Q#X=3!{t=SVkpD+On^0SzY)=a@q>{yQA&Wktlq-1vIU(a)3jH=hw_nfGDE5l(*x9yUkKC z#Zo08RajCsMWn*^xX8;u3L-;YT;%Jx$O_ObOm5rDz<^H4iTN~>cYe^L`v*q+uMZ*8 zPXi3eo|BL+H`f5&o&$FyH0EqSh<3=y130MK=@3bNvh>*8j7FkLiV4PBs|UO+RBc|!AYiU^E4 zd;`74zeF#!olNZ^L_2)>cZa z5Y9x_dl>Zqr!XxPIfNoFAp)7yT44fD3BdNsJHA5?nRnZQ^-S5EKAbqiD(`p~2*C|{ zIUwKZob-|FjeK`NRl)7YS^a0OhX~sPm?|jmc$8C5NDuxBd1L;MbRDu@_+N~d{(~Xu zHzW`U>vcRUqK;>fy0)F9hlVQ zb2_Njz}ZH`)OSU+zv^h4DLW7bwSygX=-0r&&LDsVuD!e?4HHLAt=_o|MKjwdZ;Hgc z8iJS?qAmn{(f~H6EH~dvfrIW>+v%v{sP2n=3xlx z{McsO)pwK^jJX4`eWfw7!~bizR7d7sHqRhG)vmlSfzK??(iC+HYC!`$jsic@ik|FEG|<9( zN;f7n7%VC@CIdsqyls@m5twYU`MNP!{1$4r9c{&6@it_WkMZ+U^4gr- zl~)27=lOlU+B!jg&S5%HHbHeHq5ss7+QfM_2A z6L+)9Y^XSeDYGM9VajAlHSI#>q8;$Ejfqg(X7nmB0f2$^E5y6Hn?{wFh5C0SLoGys zNd8(TvqQybn#o)TnKyc_rGY1nFVP2Z_%Uc!$2xLe_iii*D3JFUWdbh$7!}3l`#55VI`V>P>c|W8bGBiK*@k%DugX(5+q5kXzayvHp*pVYW(KkR zZ}5dS-`;MkW>b&(Hq!vLHwLJwc{!Ww4g~$=rS z_1cg@8!~95wm6w(u#8Xw#cOaU)e*;ULmtIJoHkb83(bOzpS)s>F{R3)r3pV@40nr{g zFqv0t_m51c%)i)&%+*I(=63)5WcwBK)8uCAM-i)VMjxVkRNk?M28mZc3oLogB-s}boq=p3dIsS@OtjVEgbMQE1At4P=rL-Tz$1N493(2tJIG-9{A!WC6bIF4+Cw*?1x_%C-<01jf(COEZ(K z!7EvvZ3I^g*=vSJg2KUxzTO|E5T|; znc~3+OzfKgLmkCY|D&V+o>2cAs8}ZZLBxabfRPOt( zw|x7gM8bVd3G_Ro9HEkgdlb_aZ7=H=U_FUA$4K-%>n@ZN)dmdzE=|~R1oMISDq6de z^OiRVf15mS{(9;k@28xB|D|^TRs5N0q=VOdNd|C$IRh7cm^P?o!%S;Zo=Oi@>y-j`%D^%D>*y8ALJh07%w+XA#22d-S^3H(hIThl{`06to^}sqg*iV z?IS2A~kC2BEmKRimC0RV9!Q{=32d zOrnosY6XLPP*m|$RJz~7z&QboyWcF6T|4mJQYJgMmC2Ru^1Q9`yjHn?%0#(;9()_k zpeUohbveGgFatLAtJ3uPSWQ&z#x705#&vbkoQ_v zkGQ;Kn$hG1SC#D~D-#j|lDrVskn^1gIsc47SPwa`H00dH%j0wuVG5&TZ-=o zljnS5zJ--Q!o9#UVJ`$>`943PnD*;>H|h&_DZ0I2KE|)})j}yke7#F{s|Hce%&qW- zDD?AJ;~n-5@}^zF2$k#(o`JMhw*!o~%D;i~_H3tOm?QX!ZQi%I6c>l3p!(oXX<=-_ zPl+xK_3ao&#@JtS2iO7U@c(yRhamj_wZvfiJZtNGZSW5&RV(u2uwLDHv2VC7%o&Xg zd8tD@_dkKCu0!q*qxh3XHY5-AFOQ|lE9iDhG9>kFFnfSplW%Vqf}f!am}Zn)64dZM zO{QP~k;_$5v9U~E@ER)5yZA<>aiV%wLN~kQ{#Tg zorb`BR5)kall2@$W8Wj6c@D)=owldRXWGzlIIN&2j~2|g51yg~9Q?Q+vjHRAe!%lW zf2%OeiKV|dQGaiNCqaj$x>iV-3h?`AAjPxmK+ zPF){U=|QEh;_rQ?UwNLPL#|~{H>^8YirO>3OB|>_H&_Z&)Ng5ni{8IU zrqbMw{>@yfl0Eu2V{fM^iB>Fv%1sB+m}3n0{B6)}r;X%VhMblzm2ZCrG!QwzhcFMC~*8nJ5kmF>+> z^3<)FJKsFmyUWIK8y6>gf4kb`xeNZfwR0u$iTRurVL2{2Sq>Y-6S9+FEhpAMAODa$9Gi?a1An>_dbO8M++3YX6c^c14o z*)3qpkR$D<$Z-Wo+2mIe8c;5uq1Un(#qx11Q+r4^wU>T|srB>T4O7Erw?-7G1bb`b z_7*3|vo;}?Jn3LBBoE5yl;v^*NZI6<6SB#DK^}Ok+jjonkY~6rTt55Isfb=a>0r;0 zCkthDN_psq3?RzUBR2Wck?SDL;aI}_5R=9i?E)UCdR!n&w7366_S)Edz z?dV$A{3+{VN%0rm#J2qm6YJxB6eji{v#Zw57H(gUFAMX34Kj^h9#23rqdZz6%PIM% zc^aGi9IGz}U|$_5l3*-h{x|E(F4P~RomqkYMRa+p1bJ2=d`fv}UCbu0W%Xqbd2oBIKLNGmkVZ2B-H_#2ELk4Y4Xy2G z7+P=dy)d-9F^^%io5sY2(H}ui9jzf4XjOLZS9-S-8|^e95$uPCO*1#4YoPbymnXb9lhaI$5JsoZC*)zjP+(YI8f?eF zkKiZh0Aa&kkUm(&qML}E)cE=>!56U-D8_$=Z9d}n`%Ha0KGGj&>Ir{4m^k6@TUfD& zzmK!x3V){y-~Yq)xrH#Glh)^Upx#Dq*gOhJ*@jIS_&;TR?yVg?*602M3J$C#6wrEa z=lsxk0J}Zy{v^9PInC~$)Lo!1>auU1)J>WNEE%vg+omK6TkQVZy6ib8JpF*rr?D5@ z1gyZM3>@VcX!mW-aO52EEXE!edti2&T|FC#kzkYeQKF1#GPacWBHZU{ENodJBWAYm zfGbU1*=Kc}r%`Q1GlAv1GSv}xB3OgUPkv45xqi222{b_KcR#TCFp`Pzuz8g)%Dq6U zQn7uht@GDx9ny-;r6Wj@&BA)zep*}HsXPw}>A~9KHf$yME!GxkHdJ4a!zjI~E&6&~ zuz^jx{C~3^r?zQZuuUYjTTwlIx~WK))Ba6bi`$C1paS~hvK!wF8nNugRucl_i|n*& zaBvYB2bSFe6cCo(K3`1Hv!PjW*=;GH`m&pcqG;LeUebQ3`_~dGMme-Ilm@~X4u3fo z=dt;1uY+xV!*V?KXU~B7V1G6S%&7DQnTK!~Om2FYES8qzp|V=G3f~WC);(6Ng2YV; zIIc=A$o!htXg5z$6Rw&PNVteTn1Rr45gZIzS_woNcC>fi2d?ro|E&H+o z`c>2b9Y+&ZNb|Q?TgyAP50E6^_a^zSi&Lnoe zmCgApi4A3Qb1Oi4kWMD*K?~TUpq$yf22i|cH3BcTsNruW7L4CG$!Algio2`L@^e^OFxrp3V?V6qc^*yn=eo15tx6` z7m$ZplDo$BM-+|1K=eLu%0-FB7z@zdhU!DPNvTD`L ztC0&B8XJzlB1vHUBz)ssAR_5>3=>qzY2HopHoXRU0Ao_;G!KMUw3)gP%XI2Ndf=;L;y)CjWXnZQlBz}6KeY|k#8$)_nZ%Yj!g+M%J>-yK{WIC z^+axu=UhY0Y|~nK$9kM6pmpT!qy=_*)8t9DVJF>pzHXDe;xlBfr+B3iTGY(6pB(Hk zKKucagnF&mAc!jVPZ9#9T1ZT8ZeD;F(!j>vR5G{AnXIf7^|4ygMdm+q3AyR-m<>|a zbs>yrsgkoB8~0_(;w3`Eextgc`C-RlnOyTM6)zM*SYxc>Jy!#(p!-DRYTJQ$J$=TRHV&6O& zMnQRf1kh46xhxtBZ^;0z>jrr|5WZVpUQFiZXYp8X#jaAFyiS_-&hq*~n|5D!sLxVH zU&&`+A8!}S51kZ+jx0@Pe$CISx8k3Pr2!jc!Ge}a@sA+>*KH=L^!SPB6RZbgHoU1% zz`%4q>LnvPh*zL~Y28Da6e5#cD5nsbZ9x7?Ab%BtdXbQ+64nCxrxwP)0|2>sA}V9> zkEo02kI;H*^JMDvq2rQ|74&52q>TVNz8zWt zkOap$*jfZvQSgez4RX_&q)|1=?weeT9RdNC(Elt^&QrhA_1aN`c|*NDR(CrB-Zh9| zywlN%c*d?n^{(Q3M6*a&cWz?F##4qc+AzKu9z`?1OVqfQf@YW(?|+=^Yyah@#&`owv^IT1l~LUsa-{dy5J$6C zDmVm<&E}X#uwtX@WKd?u8k3OJ#`Z8e0)xvYkgK@-6&v@P&24BeXsdaI&-5V0Nx)(N z!|qz$%^h}LW;eWP9>~Fua^oPE)J#8_3kSrCq6EiKS>YO9Es)Tz__N_5H1o%xN}lZ; z@IkGE65u{I@GPlRPk{X;Z!rhhd^JWpdFpp?pxt@MATa)DE@^Q+(?En5Zyp;S4+H%M zCO2z&n7@6QrStQ25*vX*Zc z;oJzX5pLvxPzicq`#GRf>(qxB*vu-4geQ0g^+7`&HYku+R^~on{#1+0J4StltuYIM zNoQSQ%+J=6s;ITSxf8Gc3-wUs0Uv83c!Hfg5J3UCp%sE{k)$`@#og;Q$M* zd+a%r=Xjh9@gpz-(sX_T**y;*Nku{xfpv~Fb1EodpK2k7P>;}AE>;^@O~GDE&HQV| z!sI#jA#mI{REsmY#);bBYvvoV>shZA*zQWQ>}Ol?{slNhCZ|rct$Q}JFi8agshC($ zZSEk|sm)#V+T7f&N7%2JJx6ZB$pg6kT*kg_T^zoAC(zM=7}!K%!@QBbZEu|2KRt_9 z&m4jDN2oQO;xGEdVqSgF?G`V8_rl zlJq0RKaU@r#(qUYYu@AC%Mwk(7b~%il@!oAUTa4J@p1^c`4)0xxIP2XFE>IT;cGOs z!Kp~k>wlC+5Vo{}a*JpHS3}#p0qm1Nai?ei3qD0XmxTEs_>cF;hsvM%v7=Wo{|5BR_>RMsOQVNX|M&0n{dAln@>`&{zVt zLUj=;h_I*4&E#JQ8gW0R)#BOyo5GbG2?A6a5R5Nza5w24SS)Az3;6$O@7ly^)& z4Cy}t_kusfv4Px3`4gcJoZln)zx&#d-(F%gj?mcZv6SMnjVuG+uuch_hnD>c&0Ka`Eg+2tqK19U{QM#X8 zHZUaSi}+n8{#$k=mv_k9d6RY<)B`qGLJ%|zcjS;fN03F(g$Q1rh~CMgdqEh@{2z*b z9Zicq531+p2vj5oA4226Tgb8=rm~%pevs030tx*)5=%2*L-Ocdi*n)}yHk)2n|gQw zakT4|x(}=~@q8JT+h_R!wo6)@3?I%4DNaq7nH8sqkaoa*qnGr8s>ycMG~iFla`tr$z-YPqHcm+ zlQRAD$(mpb&Bss+t$TtmqOqp=y+Gn1q@kV?OBH;NO$GygKXVPt?q?qa8?-&DtOd?J zcp+1VQ9njGxxPxq@czR#NF2NnRG`Z1Sk(@9arOWQ<6puUgt`Qb7m+zD#ZLjGp5)i8 z(v4bez_)XF^FvhJMk#)Q{#7aJ$BR%KF0WzsJnCJtkihsoqbZL(%A+@AgeAC;E9OU# zTMdaCVGQ>HkL6zvdce33MD%Q!GYc?kM_Fbx8xUmYr;T3ZMje$kn8q*$(+~$s$T+-{ z!e*AQ9ty5M#6<4R_4Nj${3s{~KV^I}H8EbkKyn++^zsu^Ft3#)B293NBQ|+X`jOeD z#bkkjQBOfiRzV&D3RRE;NY8xfgCG~?#OB)^7aT^cM7Apfp-cE(;DT6yRi5#8k0Mw% zV8QFaV~-SHB4f=wgQqwSaTxQ1SoYql#KJm@DEu2TpfuhAP2^Au{K%rX2T1B}^xlKx z;WmNtPlM!U#E?W!kwk(Gyt0t=lt6kq0qex14$~7HEK7-IB%r7Klb90lW~AgQVHVWE zSsO>J=^fl?9F~I`x)GF#W}W~NV6ub^mGi_5=Gu{@l#PfC>dfp1Ri+t;_(Z<2K;4@Ey9tGbHWv{V$Qwf~E1)prr`6?!*x353(C4}bDJv5sWpG43E0U1WY0!i{G{+`7~kWuqhc^5xw4;g_VnK`Z2@`hkx)O(zf4xGYATkt$FEl ztgUip3J#3nh|x64n(U-Hjv-$MWb0N$G2yZ(RzF{V3q-bVC3+xhAjn4YCwcN=hzln_ z3}R@@82!gk*;w)f0FC535N5F(4C0HhZ_SAPZzHxptemA)gxLFx*k2(QY^5VEob@8a z8d*;;vVM1dnD{IsIo&40h?hVXBkM6n>@~1t7V8pX&(UL>J_cnvM-~|0HUi^|Zj&by z;dT~|^PJz@im!+9g|^a9FF79z{h{_4B_W*CKBG4fd>bml$27FT3K%xBha}R#<0^cbD5q_ zXaj&IXO^bpM3N&t>jlb#9cb1wT5~O_1}Fc&qT4WV=?6$ufj8{8MYC?j8UhS=9szLL zLlkN}4LKkbt|AD_1(VLBv>PE3If^jHn)wnzq&pDCC^#QN^}xe10~V8lKyHF&?qa-f z(Tem`B;0xF2Ic^UDQDumRgk7e&>smbNVe`_Ztf5B7(1P3u=z_2B5(;wJ|nr2#oHi0 z9X0q&DLKLwL~a)Y5-b`fzBmVwfke}Ay;$g&OQC#L;uC<=;i)V_`YU~$mAG1m<)XZh zCy2AI-bE~2O4p674_)vlfrZ#A8__i_%$Bh zM&UMuTR1z+B~WSUHFY0YFxZ)kusSeUfn32q$7l6Tz+WriU&`^bIhXGdXR|3+zj*;- z!oGD7zKmAkO78bH7M%Gl60xpKT<69I;4V93fziko;kekOWXzz=8N8EfWJH!2qNG zra=E&gjsASb({R=&9lYi?^3MZtkTvuAY2f^z&Zh;9&HQ|%m9TMctAkt#}N`DvREV_ zJk7J18i6oNK$y)D9=}G+Vk8iB8Jh+}3d8n+YZ%)SMuWTE4-m!<?29Q zdKvTlUjr~9nLK+pg_w^&uH@|Zz8$OwWpK>Q9r}@8p?@@14o3AD!njB4g;`Wo=Ee)6C6Y=lM{$!xdzHL2=77|`{a~BK5=dNN=`!? z*otubK*>0 znAm@I0A5aXtNZK-S06kN7XA7o;ON*!)!iPf!Lt_?DqO&`pzJv@w z@F~ofY34^M4u@%}TQPv&NxYw({CbKfi%m>Jzq%Px<^y?*PxTZ5NU>Yn`%oR0;* z!Tl!)!+i3|dW3FC@DR8WR~iI(oe4gJq^zh6E29$A%*jI1 zDuf}X(aFQ@ooZon@MfMTvwNYYz5%5h?2bUfDC`m_jp|ZzaI}!S!1x^kk%I^exd-Es zL>&G^KYy!GSDl@|z2q{4dYn&r7&O^=JgTgy^EgIDXJD(@`l@&amh~U$d|M&@@f4=X zn>MW!kL7*FkCgF)eEPvx*hI<>HN`l`dpI~3nNU9q_HN`mIU-*=A`|@_Aj=o$Zskpz zg?x8<^?W5FV;s0WDc?^}EIi-8lNHio*f#(Q%j=GwZ^U`ueOTw(hl9gaZDF~0df(@A zHxju}{$I(LiGp_pos0pQ``PN8kf`gvX2ovnn=8qKD2KS26YEvh&6vx^mMHB8wx)A&~dO;Mtss zCe%%;o$p-@s#KmD^+`hZ>tmVqJU9I;V>1u6D5WK2mblFYNkxcvZ}49Lq5r0tZ!+lr zK7#(4QRyc}r(b$9{i_Z7gNVMauW>93!yaB|7R~KpYmD>0IKEQJP9U?>%w!CFTgw*Q zTOgij{sg+BGoiwX=AL%Y<5*rS8+Z_u1fPTRzTv_-+RFAj$>0aFI$WQhjkuOVVQE^>>ai$mL);`_P ztEVGugL%yC^fT|jMrjFW(rHFj#(DIRJap}j@ag@e^S?CnC)1FKpTJG|6{R14`9&-z zeggMqMANvX$N5{hOq^rxf0=#&cboSh_Zkt`1oW^=?^o;|bbZ_&d7d{GJ$_zM_r537 z+k?Rur^n8rK12$La*lTowqr-0Lk*wf6%T>Z8B}(}9E&QB4s3lVQ$guknki5oy!CDD_-eKn>j-ahFp@5?kOjc_)HgMViO)m)S~ zo!c#@`f2D3og3raGtL?d=bpp5qQl1(n2B5fJ#hU9C!4{yepDa&0X(Fae>1&g(FA_v z+2*<)dLh9`AEX!33D*a7!7d~q9XO$-7&;_|(1E=ev3OO`NMTp-E$Sif3Qps%H_+?jhi%V9 zAC!j3)$Ks*pYUH!n;DEaHBVuN1mpgu3r<3ipc))bAI$ zL&p!_FGBcj0{V~KFG8rBzKXbCWUNk4xL;&3HS_@`8J7s;Y?qr0!M`!zh;C^lYX^f1 zXyVL>rybDvor5V%Cb=n(^b~6Iig*V?&PYfP-%p^o*J&wf*gGiC-HA40raX6x+}|;i zMp*35l8?DFI?Ae|?mT$;!>}+&o14%g$nV`BeAVzHxc|f8WgVsFyr8Q5k+qKlI_X+A z-|wh|0x20>VBhUb;6`R&FQ>o;>28z=6$|%^d}r5XofD>y%Rih%AJs!8e}Jm^p3-&@ z7h>#7P)wWPf8ifZsB>@X_$wmJuljm$BCd=dusI+}MY@`Tx70}Hb0>>}#>hJ|k z!*Py7^-sT_qo+%Ny*^KF5Bi%jS=ZlcN*=BctgoThhrht|h5GOSIob<(eOMc-KKusc zFpi&ul)eoEu_$=gAR;pUseyPI=L3JpCrWt)2`W3$Wx(A<>>J}4v{3!Wh5H{|vJ<|~ zvA^aAxM;!ifIggIhz@P(CI zAi0r>$vuJOMi!{*2$0;+j3M^~c%~_I4~pD8&yYI@Eoxbd{BkUL&tdUsYqSFq2G6~DiOc$(1t5NL%;7}!$~mwzQc{s{$b(w z9X#k6^503g8NBGf?_di3zQZyA9e!JP`1c)N+KYn2vs6)2(sB8=WeyR21{5}KD zb$)y2t&{;Ye%HZar5_@2(C<2g>;toq+@D~6v7IIv(X*w4d+a9h#q1_=>|tRCqpXkz zRe)|1chgPcy~uC%T#vM=hw1kiihAR^%p#fp9>Z`*&3=zzE8V7vGj`Mb=k=eao_Dq_ z=P)kIq`qN@9~=KYhawZD*MHC9UUU?U-*afUVGcN)o_^1Pu80n$hhFh}4mH%ZcmZ_j zp_^pcIX(3)rS0>?;5-rExU{q$cd^oirLRDbI3OuEsi-db@>*O!n78ukG`hD`Zt@aL z-8u(j;n-p(vEXz_<5gCa7*M{!O2L6w&!3P&A_a@k{TV}A2R%bart^f#2$zW z+PAq3=(NeP4XUHxhbTndEJUa@Js0bSbXRsR-DQd9pNM}CY?}JUqE8baeqm!KP_gfS zJk^&Xx<~R|{pTXSz&DOb3(#bG8l~q7!9l{V}Au^(7Wi9?m2Yi9O6F?fsNGk zYjjIlg!t=Xa`Si8PxEbPz_3rS-LU;oR&R`Bd16z`K-`y3MCi96nsy*_>w(UH@_Dfr zz%DS*V?~NvbtLac?DGT>pqtotuxr`9TN$(#NWShA`F3)IzHY3OZe@Waxv4>iG@n2K z$fObrlx9JeP}*oBuYSmORAaeYZSN?3Qqx{RX(3VtBTN;10eUVzgGnf7-rnQh$up5S zFn*#8?prnU-zolS)B(Le0Pd$VcJV70_ys3$jROxz4ld|Y@uz{#w}N{6c3N9-?WY63 z0EjhqNQ%>vMNCyFgqsn-mOG>gs*E_dA1e7Q5`r3SB%-x^3)bx!)y)ddtL0(`04;GR z;~=PaY48!aFY<$QWTfdR60!wAnuo($2jMB365>$Y9<1}@R{1QsDM(0xYvBFQqKy-< zf)2SU1!SiAFhCObS3<^a??df!p@&kc>>OC z%K@>NQ9}pZl*w=(1UoGHa)yT+IcXu%*DcE{CX(u4jA+krZ8-h*S`K6-#&eN^_yI0s z3cK{Nb?6bIz@RYw+~6QqaJh6v$AI*eMd^jXL_os*AF3cAja$LXI|?z%Htb$*x{PH^ zl$q`OK$q{);N{HZ4=geHG+fZU2`bAyx*7iNIS5U^%tkjF(>14sD<`EP2G;%tAS#Z7 zJ(o8gXWH||o(R4K$SW2k)y!rlHySnEdCnB^^;qbM|7szw_oriQm+SdP``xX5z~<*i z*zb5D1-nkGkX#f>HjAt)6X!=>23~M1prQJS#)#dn9P&?UxAw+#zax=;|0k}Sq+4zV zpS~|}IkWKlKgqaWxsNTU8|?*MrtHHdR;bdq-%YloS2r?Mk`Cf+BK{)kTM;&F>hj7meTMdf`MI~355 zp!&Oz^1B3xWZKvWf*TI}dE<|xgpLQ#B{vRuMQBHq_e`W7)1QPomQDZOi)^tk6aT^s z2k#9K-|K^~= zv<6OV;Isx#YvBI@4J>k%c-(bk#}*e9*SVZkRqm4F%9?stokuEi)zrJ|>Mb>HkEPyQ zTkEd#xJrjg(`#Kd`EzEBwO3WS%AHjc-8G9`b@i3_>AGn^bXrPWRaF*FbtphJmKtxh ztFE%d;#pGb8fzI`FXdO)dX_}u*=tJNHT9MC9#@UWQtkBARW?}aD{peu50wz%aaPtK zkD&$5S|gJPpvArLdWaF`%~@BDOlv$+Wxb0slP0>oRi#Xl8@;Z&B^FPG3)$2Tm2Pk? zsTX3)T^=LOLQzAdMb0X(D;5fm4Cm{u2`Ne{a=Vd5%@W43tH$juuMmP3gGFRvU|QT> zPpua^)VW8LO%GZIms%=$Q8+F2P)|+yP^rdUQtpvuf&GCGPSXD6`a3;;yc(bJbI6v6858R+UNhAO<33Rc@yz61}#v!BrJ5x54!y zYqM%@sBtf@v6NIeYifX2>hw4*W$rqZUQZjD>2Z2oda+lbkS*@AP_i0lHI*{AiJp-} zbEssmfu1W%c@AV1V=eQbkHMw$p&$>GvC!*rS;}3o5vK>DS<0N1Ridd1Vne`C5m_SS zD-Ch&YAA8l5}^p>>V}C`&iZNtSNO@ zOVyP%Qnj-|B5@_E2~w@APS2(a*6pm58tR?ZwFs9>OF|)5cbur8AX?)F5f(O7Uti*^ za@Oeubn)Q&i{Wo3qKK#=T}^;Fp*ZpePaIg0s(Jr`LhxkIFbeU-StYrQ2}wxXQ6&fImP zZzD=Pg3+i)WvnSBP4%EwP+4D(%t|UO3tgVYE*JBg3te@TzP8T2sIrvmuU^+!rLjPd zAqcB|2D7A+2_r|&v(48lBsg%R-dntIv)luK7)!Fa0y&X44A%w2(I_^@q@mJ6SanG; zmtZUvC4$}(Ud^cJYrJsxx}C9Vio9=mNYfG?*0gK!_agqzdqmSx9@Vrj@z?a2rX7D! z(=G!}(H}MK&c6WuC*Z8cAKs3?BF&!x!}l|P(6n0~=XWWPP0>SN;va4h#rkyPRiD19 zY46}~$ZNQf5r1dmuNVFf0roxqcK=7ya(8Q5_S>4)iuWAco>TFTrmehdD(i<7$-UeB_l-4uvru z!I92m{8gqt27A-{hB%c*B5gL(yn36axhNBsE|1dLNVYh8C|QA!jHRokykIv!Cmrd3 zHPVekx{D}3JP!PQhQB$0-3}W{_y-KbaY}uC3yGpAY;s?sM`xKHgw3WBy``WRQ~!CS z|H-K>rnudpmv>SDOzul%c`a;z4s8Dc(B-tI|43QJy&r=$W*4hL>xmVb_8;&Tl`k-% z+r{M6MpN7^AU5$NzViB#U49K(xu}Eh>U`Z9$I5Ohx68u#%b=vNVJb{Fg-G+IU(+r? zy-c_l|1jPBm^|?Rwa)z0nEg_XRzR zE?0&})5aj2K%4oH$k%H{(w&KcguCMJj>`kQ3;BKaTTT0rDhX=d3Xp)aLx+!}n$NKKoVnmiSmG5ZJkThKmq_c7>9Av&nr@q?2?NvHI!5K@wj zJ&64C{-SB$klfGVpHu6xF}m1OnT@rAkFWoxY4=cBp3?r~9*SBd&>;DPk)Wl(*ZSbp z60QPoOg|I*B`J5u-<1$ZyfZ1!*DJoQ&rr*Pp;Fwx`@mH?NcS1|t3}#R>ojcu$~9p< z(xxP(LHBWYCIu4jO1L{d?k+;N^`*K@zP$Dov|k9*L%wPyU{!$OP=+M^CN<3$H?I#l z#kufi*jOd4M*I_qr+Ot7rKZ(0FNdT3_@p*rFXA3g!3WbP%Ji;yJNe9MWJi;zZshYi zyUG;*d~_!;t#8~*P|wM=c@l&q{agkYnSnO>t&?mg{z%wd^7_Ut3>CVa^pl6b3Z#7% z?eraJe zL2LI%nszSU2_sN&G5sBDZziX%F~x0(s-Y=;Envq3I!9mwQ(%h;lR*y&#QFym^npy0 z_Q*x1vz8`qNHRSdw;FQnNlN-ANm|wm$;pb@1H2)`-z;Y^QS!y1>iFXWrq2?k9SMMT zCL|%KCMF?rT_TRWF`8%p&Xl;Pm+6hTJ7ExC_e#1mS$Z&8APSl}*1M6#m!`Zsdr7y) zC*IdfdLw=;!hcUlLinYGB!o96!h!rQsXu}{l92rKr1KC&;)Egi67u@*UZz8F>mk7Q zUP+(!k`9RiXpg*TGX32&3@QF;`a^tIM*OUyAg&De2R`(h(DF zV_FlR)Y(_s5uXJ3r}5aA{8qwOragV7hkGU6n7XM zfA>M~i#|z5`byvSLAP{kUqVA3iIs1G=IQ6O22N|>v<6OV;Isx#Yv8m7exU}+s56cy zOMko9^KXy-UZTJ6(BDSS<2-D}q{sNayvO(09^dvJ-`Do|F6;5_?eXo?ziGTAKG;^q zo^Cy!hCJ-a#@9=%)s=zYU)PH1id z4|>|{Y0>#XcaS|6oj@P`JIl-iG#;Xd#&q<=^Ov;lOCHe4N)4CtZ-b8toe-`G zV~>&Ec3?6?>|2FtA=>BiLD|9{oZ_ztV z=d=d?f2o14=u%IfIB~2cgBGitmt$4891E-^B^K+5p(BQ7T|PWh4@FN)Q1TlI(qVm_ zB#d_!f^kw`sa9_{{-Q@U>2OOv2e5g21p9yx;df2qaGGPM=h7H(nlmB%++2nx(Htf{ z@9Xfzx$IM-`89eD03MCcA9Q^G1dc~^>B&U8X!s)mr+nX<$nlJSN9*u!d%*2F+-N@y z{9?dO(%I5Ly;W@b^w1guJwf(P zm2x-pZ{y$NI(`;TEz@%me@V1XW|ClyI{!LY$^o3{w<;Xs(j)$?~CGko}^0LMhNVoy5Y(e(417_%-vKzIznGy*Z2b_y5fCbx{@pR)_r-ue8v}k3ln{-6ehm2R z81VWS@Rfk$|C64z0D`5Ho=q|EkH^4I0Q1rKzmUOE+PRTg432?+bqx3ofJfu=))@FN z08Zt&!2W-lyP6o+ks@p@;((A4LPD(A15ZLLE?~u(zeIbPOvW?gotaEX@_u*{YB`Q) z#%vr9jwh252M*l!f)ED|oZz}bdjaWjTZE9fAS90L6M9_suopP&4Gw(O-R0PhJ(-us zN^5D-?Q&Olb#+yBb-T->+NHA)be&;6jz>$^uPfmHt$=?M?}E$dc?<9|J|`9B->rcE z0`RYZ{(ozIk?(Lp^V}|STJyKxfOW3$6qsOd(KLxyu&!YvCt!(mcMg703sOPt`JpAGJ zRW0iHZt+{*g(r~-Zsc$vICuYi968+H#Q1^J)X0WYiP?TYfFit;}Pyo~;5 z74VNL>Ujejjb-#0{ye^kgT&_}uBLZ&Wr(MpezGHkH=kRURnH#Ybi96IStuQgBzA*j z>UehF#gA>(ari$y+39ovnhivMNA#0=4Qu}!Hy#PJgwxd#klhP2n8vPIQ>`^bZ-^Rw z-|6f);knol8=D=Ra<==)=9L@7&T-!ooqkPh^~X3#YXff8MBg9dc(651oc@-eqGKFO zcTkdOB9PqxQD}1N+g)I6a4TXGjeJ=mLj`(pcyhMaIuW8Htmb3l%RbJI@7L`aQCa!i z($BYbR0Dde&N4TWsDs1gGc=WKt7rz~REO4JvE5CX(@c-7gB9p&8-2CyVfT2}8wk^j z#v>#2=La~dONVR~K+!aaz+WC_Yl&pbN}@&Gs88W~aWYNtf22(hXUJp!f`TkCilOkv zh##05LX0ADF^-1rSd1{hQ{i6E4LT=0_9@^4!(3KEoClLYxN+>>3Pf7Ox5jylQ5U1@ zFuVmy<_-ZRL6R$aodn|`32^XV3GLw{jL~w3Y6!>ZT!-!M!>K*9cW@Yy32E3WZC`ifLL_JCa#Aq4`b?&|#c^y)#MY_ce?>{zU|J)SfVm=oL zc$h{LusFFDGi^M$6YI3kh9Xt+r9pwYlYt5e*#hSrX01CAIX;Dk*#BOqb?UUi=fNp- zv3iK}wFTw1l}cugj8PTh!qB`DH^`(h-=7Z1DEo6V$~${xOXr?lE&(~VEX1eMK<2s8 zX*vi#xI{bFCIuD2qLuMl8|kxygT6fwgVx@OE%j;9^-ssfN`cf};YrG}+A5mj1Qu~y z#k|?wW3PAI>5CoxjF=^Ps3taRbAZsDQEFwKOurj27zkV2*l;kywrzy-eIKzB(QS)t zByOE)8v!Q7{o_&^wuUgy6FDK>v&qdzzQ@g>TCR2b$ai7t+m;;!=jcvmY=BTFML0(v zn`D>2c6XNWQHQ$z>ef2=MR%#>Y*!Yb(@!!=H>kW8UZ5ot2uYI=gJj%V!pAXDQ;? zdAoPqC#S`pb(-)QCf9NugXPSG!b->K8pP?MSbv+mjH|N&%^)lE$=YmVpfN)Qo^(5v zFu)*VHALQaE3xN6qSgH3n$|lp7ATl7^NL?TUGJS$d|Ak@ znn+kloaqU5!X5YV=f;Eh+9!gSM|K@Q1*=PP+!`3XDiNS(_Yi@G=*xLsivSe5!Gkb# zM|!<6@malRS+zFn%@tz+S76p#ba|bwazA@Z!->HPy{p^Qa9d<&G7Rp{2)A|zkLcMw zc!Y&^9VJ;!Qu(!NXEN6O0D;oh<`iN{i?=;26X6X=56H5zAR>?5izO%M+=i>sJ3h}9 z+EGi&!6hc^5rT6kSZ3u46kVxT=e1lnNmBYv=~gnu^%{D3D3`cddIHchxe2p!k)trf zBdzG8ad#GGOoB;Lw8Hi@2AKHU*tEcaL06?WIEdiAtaeUFZng#(B6yNs9LSh-RSW!y zZVY=hO`zw(yL?Ab%zG+N5GPvCR`muvVn&rR(RrGc$F$3Ip^X0RDMqd8MPqM)3#o+tTY@}y&LKz%tFen+-Y|rP z$(dHOE>&VNu|B1{38U7FHX(4L0f z^};X+M#G^}M%pn$4lXi%^u!R(0G2M@KE_TNZ5|KYAwC=<9!_oobfV`^;g{~>;2;)G zwN&a!98-}mF%C=H)>+>2KFkuiK`>Ni;$>fUH0fQ3+(58<;j(~AwNWbo*Zbjh5EoVe z8DUxSgI-;<)y^+Ec2_ePx1D4EmR$-AeHcy16NnSJJG}xoztKaBHX2)gF_0hGRdi&w zkksmrjr$UB0%cmrq$t&TVy;)3EYSFEBh*q*MxAjMc)i9^GVd4&vCb3E{ zIfrGadFf6s4HNzmim5b-4U?Ymx397{0?)8~bP2&Qr6XoujT3`@%!>$_#D^1Q(i;?% zjOarwhUs7GcP5u3;PV|?@vxkfUnIh-H_|s*qgvjmIyg`DP{XKF5=qV+GP3p|lo;=W zLits!{2R~p?&y0bIBJNqgZko(PU(9ibm?Oh{FxA(4OJJ#PvDB56a7>N)33qCcafoIjL&f%oN}B8x6k<8e>$c{ ze9^Dr4PzHKbnVJt1FxfV7mphQU1YNO4|dfPPK##@_@2}A0)9>7bIRpZt&9G1KcWKu zuEyu|KM7;1v{>JD0iWZ1IK^?t+*R!Vk2L;kTT4wX_E=l2*vh)12~S>rTWcrQH{SV zgkpPq&*|?`3`gfud_LE{dr$m70hj1!`9As>H@J>8{sVcp_~CXL@;78i_8FhgV_#}~ z`c4a7+;7I`ar^|ZK-`bG+p8E%)MbS9<@|MOo|C3Q7iJf)if{{vBK*#`gs literal 0 HcmV?d00001 diff --git a/imgproc/openexr/make.m b/imgproc/openexr/make.m index 88774776..98acf4cc 100644 --- a/imgproc/openexr/make.m +++ b/imgproc/openexr/make.m @@ -1,43 +1,52 @@ +% This makefile returns .oct files as replacement to MATLAB's .mex +% Some headers from cpp files have been commented out either to avoid conflict +% or absence of those libraries in Octave. + +% Thus, we have a compiler for Octave. + clc; verbose = false; - -% ----------------------------------------------- +% ------------------------------------------------- build_files = { 'exrinfo.cpp', ... - 'exrread.cpp', ... - 'exrreadchannels.cpp', ... - 'exrwrite.cpp', ... - 'exrwritechannels.cpp'}; + 'exrread.cpp', ... + 'exrreadchannels.cpp', ... + 'exrwrite.cpp', ... + 'exrwritechannels.cpp'}; + +% build_files = { 'exrinfo.cpp'}; companion_files = { 'utilities.cpp', ... - 'ImfToMatlab.cpp', ... - 'MatlabToImf.cpp'}; + 'ImfToMatlab.cpp', ... + 'MatlabToImf.cpp' }; + +% Header and library paths — adjust if needed +lib_paths = ['-L', getenv('CONDA_PREFIX'), '/lib']; +include_paths = sprintf('-I%s/include/OpenEXR -I%s/include/Imath', ... + getenv('CONDA_PREFIX'), getenv('CONDA_PREFIX')); +libs = '-lOpenEXR -lIex -lImath -lIlmThread -lz'; -additionals = {}; -if(verbose == true) - additionals = [additionals, {'-v'}]; +% Verbose +extra_flags = ''; +if verbose + extra_flags = '-v'; end -for n = 1:size(build_files, 2) - if(verbose == true) - clc; +% Build loop +for k = 1:numel(build_files) + src = build_files{k}; + [~, outname, ~] = fileparts(src); + out = [outname, '.mex']; + cmd = sprintf('mkoctfile --mex %s %s %s %s %s %s -o %s %s', ... + include_paths, lib_paths, extra_flags, ... + src, strjoin(companion_files, ' '), libs, out); + disp(['Building ', out, '...']); + disp(['CMD: ', cmd]) + status = system(cmd); + if status ~= 0 + error(['Failed to compile: ', src]); end - - file = cell2mat(build_files(n)); - - disp(['Building ', file]); - - mex(file, companion_files{:}, ... - '-I/usr/local/include/OpenEXR', ... - '-I/usr/local/include/Imath',... - '-L/usr/local/lib', ... - '-lOpenEXR',... - '-lIex', ... - '-lImath', ... - '-lIlmThread', ... - '-largeArrayDims', ... - additionals{:}); end clear; -disp('Finished building OpenEXR for Matlab'); \ No newline at end of file +disp('Finished building OpenEXR MEX/OCT files for Octave.'); diff --git a/octave-functions/README.md b/octave-functions/README.md new file mode 100644 index 00000000..7456fc03 --- /dev/null +++ b/octave-functions/README.md @@ -0,0 +1,2 @@ +This directory will host custom implementations of MATLAB functions that are otherwise unavailable in Octave due to the lack of toolboxes. +Note: These functions are written with the help of AI tools. \ No newline at end of file diff --git a/octave-functions/insertShape.m b/octave-functions/insertShape.m new file mode 100644 index 00000000..a015e366 --- /dev/null +++ b/octave-functions/insertShape.m @@ -0,0 +1,110 @@ +% In MATLAB, this function comes from the CV Toolbox. +% Here, we replicate its functionality using a custom implementation. + +function imgOut = insertShape(img, shapeType, shapeParams, varargin) + if ndims(img) == 2 + img = repmat(img, [1, 1, 3]); % promote grayscale to RGB + end + + p = inputParser; + addParameter(p, 'Color', 'black'); + addParameter(p, 'Opacity', 1.0); + addParameter(p, 'LineWidth', 1); + parse(p, varargin{:}); + + color = parseColor(p.Results.Color); + opacity = p.Results.Opacity; + lineWidth = p.Results.LineWidth; + + imgOut = im2double(img); % Work in double precision [0,1] + + % Normalize shape name + shape = lower(strrep(strrep(shapeType, '-', ''), '_', '')); + + [imgH, imgW, ~] = size(imgOut); + + switch shape + case 'filledcircle' + % shapeParams: [x, y, r] + x = shapeParams(1); + y = shapeParams(2); + r = shapeParams(3); + [xx, yy] = meshgrid(1:imgW, 1:imgH); + mask = (xx - x).^2 + (yy - y).^2 <= r^2; + imgOut = blendMask(imgOut, mask, color, opacity); + + case 'filledrectangle' + % shapeParams: [x, y, w, h] + x = shapeParams(1); + y = shapeParams(2); + w = shapeParams(3); + h = shapeParams(4); + mask = false(imgH, imgW); + x1 = max(1, round(x)); + y1 = max(1, round(y)); + x2 = min(imgW, round(x + w - 1)); + y2 = min(imgH, round(y + h - 1)); + mask(y1:y2, x1:x2) = true; + imgOut = blendMask(imgOut, mask, color, opacity); + + case 'line' + % shapeParams: [x1, y1, x2, y2] + x1 = shapeParams(1); + y1 = shapeParams(2); + x2 = shapeParams(3); + y2 = shapeParams(4); + imgOut = drawLine(imgOut, x1, y1, x2, y2, lineWidth, color, opacity); + + otherwise + error('Unsupported shape: %s', shapeType); + end + + imgOut = im2uint8(imgOut); +end + +function color = parseColor(c) + if ischar(c) || isstring(c) + switch lower(c) + case 'black', color = [0, 0, 0]; + case 'white', color = [1, 1, 1]; + case 'red', color = [1, 0, 0]; + case 'green', color = [0, 1, 0]; + case 'blue', color = [0, 0, 1]; + otherwise, error('Unsupported color name'); + end + elseif isnumeric(c) && numel(c) == 3 + color = double(c(:))'; + if max(color) > 1, color = color / 255; end + else + error('Invalid color input'); + end +end + +function img = blendMask(img, mask, color, opacity) + for c = 1:3 + imgChannel = img(:,:,c); + imgChannel(mask) = (1 - opacity) * imgChannel(mask) + opacity * color(c); + img(:,:,c) = imgChannel; + end +end + +function img = drawLine(img, x1, y1, x2, y2, width, color, opacity) + imgTmp = insertLinePrimitive(img, [x1, y1, x2, y2], width, color); + mask = any(imgTmp ~= img, 3); + img = blendMask(img, mask, color, opacity); +end + +function imgOut = insertLinePrimitive(img, lineParams, width, color) + % Uses built-in line plotting in a blank canvas + imgOut = img; + h = figure('Visible','off'); + imshow(zeros(size(img)), []); + hold on; + line(lineParams([1,3]), lineParams([2,4]), 'Color', color, 'LineWidth', width); + F = getframe(gca); + close(h); + maskRGB = im2double(frame2im(F)); + maskRGB = imresize(maskRGB, [size(img,1), size(img,2)]); + mask = any(maskRGB > 0.01, 3); % binary mask + imgOut = blendMask(imgOut, mask, color, 1); % solid blend +end diff --git a/octave-functions/nsidedpoly.m b/octave-functions/nsidedpoly.m new file mode 100644 index 00000000..b9277f28 --- /dev/null +++ b/octave-functions/nsidedpoly.m @@ -0,0 +1,22 @@ +function poly = nsidedpoly(n, varargin) + % Octave-compatible replacement for nsidedpoly (regular polygon) + % poly = nsidedpoly(n, 'Center', [cx, cy], 'Radius', r, 'Rotation', angle) + + p = inputParser; + addParameter(p, 'Center', [0, 0]); + addParameter(p, 'Radius', 1); + addParameter(p, 'Rotation', 0); % in degrees + parse(p, varargin{:}); + + center = p.Results.Center; + radius = p.Results.Radius; + rot = deg2rad(p.Results.Rotation); + + % Generate regular polygon vertices + theta = (0:n-1)' * (2*pi/n) + rot; + x = center(1) + radius * cos(theta); + y = center(2) + radius * sin(theta); + + % Output struct similar to MATLAB's nsidedpoly result + poly.Vertices = [x, y]; +end diff --git a/octave-functions/strings.m b/octave-functions/strings.m new file mode 100644 index 00000000..b386f010 --- /dev/null +++ b/octave-functions/strings.m @@ -0,0 +1,8 @@ +function out = strings(varargin) + %STRINGS Emulate MATLAB's strings() in Octave using cell array of char vectors + + dims = cell2mat(varargin); + + % Use cell array of empty character vectors + out = repmat({''}, dims); +end diff --git a/opticalimage/oiSet.m b/opticalimage/oiSet.m index aa294bf7..5a6ab6d7 100644 --- a/opticalimage/oiSet.m +++ b/opticalimage/oiSet.m @@ -289,7 +289,7 @@ case {'computemethod'} % Compute method. Only applies for shift invariant - if (strcmp(val,'opticspsf') | strcmp(val,'opticsotf') | strcmp(val,'humanmw')) + if (strcmp(val,'opticspsf') || strcmp(val,'opticsotf') || strcmp(val,'humanmw')) oi.computeMethod = val; elseif (isempty(val)) oi.computeMethod = val; diff --git a/scene/pattern/sceneHDRLights.m b/scene/pattern/sceneHDRLights.m index 211d0181..50951578 100644 --- a/scene/pattern/sceneHDRLights.m +++ b/scene/pattern/sceneHDRLights.m @@ -55,7 +55,7 @@ radius = radius*imSize; for ii = 1:numel(xvals) cc = mod(ii,numel(cColors)) + 1; - img = insertShape(img,'filled-circle',[xvals(ii),y,radius(ii)],'Color',cColors{cc}); + img = insertShape(img,'filledcircle',[xvals(ii),y,radius(ii)],'Color',cColors{cc}); end %% Put lines of different thickness and orientation around the middle @@ -69,7 +69,7 @@ hw = round([1,7*lineLength; 1,3*lineLength; 3*lineLength,1; 8*lineLength,1]); for ii = 1:numel(xvals) cc = mod(ii,numel(lColors)) + 1; - img = insertShape(img,'filled-rectangle',[xvals(ii),y,hw(ii,1),hw(ii,2)],'Color',lColors{cc}); + img = insertShape(img,'filledrectangle',[xvals(ii),y,hw(ii,1),hw(ii,2)],'Color',lColors{cc}); end %% Squares @@ -78,7 +78,7 @@ squareEdge = imSize/64; hw = [2 2; 5 5; 9 9]*squareEdge; for ii = 1:numel(xvals) - img = insertShape(img,'filled-rectangle',[xvals(ii),y,hw(ii,1),hw(ii,2)],'Color','white'); + img = insertShape(img,'filledrectangle',[xvals(ii),y,hw(ii,1),hw(ii,2)],'Color','white'); end % ieNewGraphWin; imagesc(img); axis image diff --git a/sensor/sensorComputeArray.m b/sensor/sensorComputeArray.m index c01ec41b..0cb606b1 100644 --- a/sensor/sensorComputeArray.m +++ b/sensor/sensorComputeArray.m @@ -193,7 +193,8 @@ % The names are usually ovt-large or imx490-small. So we split on the % '-' to create the name. -tmp = split(sensorGet(sensors(1),'name'),'-'); thisDesign = tmp{1}; +tmp = strsplit(sensorGet(sensors(1),'name'),'-'); +thisDesign = tmp{1}; sensorCombined = sensorSet(sensorCombined,'name',sprintf('%s-%s',thisDesign,method)); diff --git a/sensor/sensorCreate.m b/sensor/sensorCreate.m index 6a1c37fb..d11f1138 100644 --- a/sensor/sensorCreate.m +++ b/sensor/sensorCreate.m @@ -357,10 +357,14 @@ end qeFile = fullfile(isetRootPath,'data','sensor','colorfilters','OVT','ovt-large.mat'); - wave = sensorGet(sensor,'wave'); - [data,filterNames] = ieReadColorFilter(wave,qeFile); - sensor = sensorSet(sensor,'filter spectra',data); - sensor = sensorSet(sensor,'filter names',filterNames); + wave = sensorGet(sensor, 'wave'); + [data, ~] = ieReadColorFilter(wave, qeFile); + + % Hardcoded filter names (since Octave can't read the cell array from .mat) + filterNames = {'r', 'g', 'b'}; + + sensor = sensorSet(sensor, 'filter spectra', data); + sensor = sensorSet(sensor, 'filter names', filterNames); % LPD-HCG - Higher voltage output sensor(2) = sensor(1); @@ -401,12 +405,17 @@ % We have the small, but correcting for the differences is a % challenge. So, we use the large twice. % qeFile = fullfile(isetRootPath,'data','sensor','colorfilters','OVT','ovt-small.mat'); - qeFile = fullfile(isetRootPath,'data','sensor','colorfilters','OVT','ovt-large.mat'); + qeFile = fullfile(isetRootPath, 'data', 'sensor', 'colorfilters', 'OVT', 'ovt-large.mat'); + + wave = sensorGet(sensor, 'wave'); + [data, ~] = ieReadColorFilter(wave, qeFile); + + % Hardcoded filter names (since Octave can't read the cell array from .mat) + filterNames = {'r', 'g', 'b'}; + + sensor = sensorSet(sensor, 'filter spectra', data); + sensor = sensorSet(sensor, 'filter names', filterNames); - wave = sensorGet(sensor,'wave'); - [data,filterNames] = ieReadColorFilter(wave,qeFile); - sensor = sensorSet(sensor,'filter spectra',data); - sensor = sensorSet(sensor,'filter names',filterNames); return; diff --git a/utility/dll70/md5/md5.cpp b/utility/dll70/md5/md5.cpp index 67814895..bfe9965f 100644 --- a/utility/dll70/md5/md5.cpp +++ b/utility/dll70/md5/md5.cpp @@ -60,7 +60,7 @@ char* MD5File(char* szFilename); * */ #include -#include +// #include /********************************************************************* diff --git a/utility/programming/ieParamFormat.m b/utility/programming/ieParamFormat.m index 6688b9db..61c1b872 100644 --- a/utility/programming/ieParamFormat.m +++ b/utility/programming/ieParamFormat.m @@ -40,14 +40,14 @@ end % If it definitely isn't a string, return it. -if (~ischar(s) && ~iscell(s) & ~isstring(s)) +if (~ischar(s) && ~iscell(s)&& ~isstring(s)) % error('s has to be a character array or cell array'); sformatted = s; return; end % Lower case -if (ischar(s) | isstring(s)) +if (ischar(s) || isstring(s)) % To lower and remove spaces sformatted = lower(s); sformatted = strrep(sformatted,' ',''); From 7e018b5136be33bcb8e95ab7d9813318e27ce6c6 Mon Sep 17 00:00:00 2001 From: "Ayush Jamdar (Non-OVT)" Date: Tue, 15 Jul 2025 12:06:46 -0700 Subject: [PATCH 2/9] update readme to indicate octave support --- README.md | 12 ++++++++++++ imgproc/openexr/make.m | 8 +++++--- octave-functions/README.md | 6 ++++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 61fd22ca..96692ecd 100644 --- a/README.md +++ b/README.md @@ -27,3 +27,15 @@ A set of tutorial videos introducing aspects of ISETCam and the companion tool f * May 10, 2024 We work more smoothly with EXR files, including sceneFromFile now reading in EXR files, and writing out sensor2EXR) This work was implemented for the extensions to HDR imaging and application of the Restormer PyTorch network for demosaicing sensor data. * April 15, 2024 Implemented a remote copy function ieSCP, to help with the distributed nature of our assets and datafiles +## Octave Support +- July 14, 2025: Ayush Jamdar at Omnivision Technologies Inc. +- GNU Octave is an free open-source alternative to MATLAB. While MATLAB (> R2022b) has its own tools to read `exr` files, Octave doesn't have native support for this and relies on other tools like `openexr`. +- We have added/modified `exrinfo.cpp`, `exrread.cpp`, `exrreadchannels.cpp`, `exrwrite.cpp`, and `exrwritechannels.cpp` to work with Octave-compatible headers and datatypes. +- These readers and writers are completely based on OpenEXR tools. One doesn't need MATLAB to run these scripts. +- `make.m` calls `mkoctfile` with the `--mex` flag so that the executable functions hence generated can be called by Octave. +- We've added `octave-functions/` that replicate the behaviour of certain MATLAB functions. +- We only used the Octave CLI; the `ipWindow` GUIs don't yet work. +- We have tested `isethdrsensor/scripts/fullSimulation.m` on examples from the ISET HDR dataset. +- Known warnings that Octave throws: + - Octave can't read `filterNames` from the `.mat` files. As a temporary fix, we've hardcoded r, g, b filter names. + - After the recent updates to `isetcam/main`, Octave throws a new but benign warning "Invalid UTF-8 byte sequences have been replaced." \ No newline at end of file diff --git a/imgproc/openexr/make.m b/imgproc/openexr/make.m index 98acf4cc..fe846205 100644 --- a/imgproc/openexr/make.m +++ b/imgproc/openexr/make.m @@ -1,9 +1,11 @@ -% This makefile returns .oct files as replacement to MATLAB's .mex -% Some headers from cpp files have been commented out either to avoid conflict +% This makefile generates .mex files using mkoctfile from Octave. +% Some headers from cpp files have been removed / commented out either to avoid conflict % or absence of those libraries in Octave. - % Thus, we have a compiler for Octave. +% Modified by Ayush Jamdar at Omnivision Technogies Inc. +% Original authors are from the ISETCam project. + clc; verbose = false; diff --git a/octave-functions/README.md b/octave-functions/README.md index 7456fc03..e1f90b0b 100644 --- a/octave-functions/README.md +++ b/octave-functions/README.md @@ -1,2 +1,4 @@ -This directory will host custom implementations of MATLAB functions that are otherwise unavailable in Octave due to the lack of toolboxes. -Note: These functions are written with the help of AI tools. \ No newline at end of file +### MATLAB Functions for Octave + +This directory hosts custom implementations of MATLAB functions that are otherwise unavailable in Octave. +Note: These functions are written with the help of AI tools and have been tested on ISET examples. \ No newline at end of file From 20f2177d083ba51e76e518acc93dfc69f75eb4d8 Mon Sep 17 00:00:00 2001 From: "Ayush Jamdar (Non-OVT)" Date: Thu, 24 Jul 2025 11:05:27 -0700 Subject: [PATCH 3/9] Update comments and Readme --- README.md | 2 +- imgproc/openexr/README.md | 7 +++++++ imgproc/openexr/make.m | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 96692ecd..8eecfdca 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ A set of tutorial videos introducing aspects of ISETCam and the companion tool f * April 15, 2024 Implemented a remote copy function ieSCP, to help with the distributed nature of our assets and datafiles ## Octave Support -- July 14, 2025: Ayush Jamdar at Omnivision Technologies Inc. +- July 14, 2025: Ayush Jamdar. - GNU Octave is an free open-source alternative to MATLAB. While MATLAB (> R2022b) has its own tools to read `exr` files, Octave doesn't have native support for this and relies on other tools like `openexr`. - We have added/modified `exrinfo.cpp`, `exrread.cpp`, `exrreadchannels.cpp`, `exrwrite.cpp`, and `exrwritechannels.cpp` to work with Octave-compatible headers and datatypes. - These readers and writers are completely based on OpenEXR tools. One doesn't need MATLAB to run these scripts. diff --git a/imgproc/openexr/README.md b/imgproc/openexr/README.md index 0cfe7dc1..ce903a24 100644 --- a/imgproc/openexr/README.md +++ b/imgproc/openexr/README.md @@ -56,3 +56,10 @@ You may also need to update `~/.matlab/YOUR_MATLAB_VERSION/mexopts.sh` (e.g. in 300 300 3 >> exrwrite(a, 'a.exr'); + + +# Octave Support +- July 24, 2025: Ayush Jamdar +- Modified `cpp` files to generate `mex` executables compatible with Octave. +- Run `make.m` to generage the executable functions. +- The `dev-octave` branch has been tested to work with Octave 6.4.0 diff --git a/imgproc/openexr/make.m b/imgproc/openexr/make.m index fe846205..1ddafbad 100644 --- a/imgproc/openexr/make.m +++ b/imgproc/openexr/make.m @@ -3,7 +3,7 @@ % or absence of those libraries in Octave. % Thus, we have a compiler for Octave. -% Modified by Ayush Jamdar at Omnivision Technogies Inc. +% Modified by Ayush Jamdar. % Original authors are from the ISETCam project. clc; From 1615b7330e6e4a1c9826a4fbaadde943ab97b34a Mon Sep 17 00:00:00 2001 From: "Ayush Jamdar (Non-OVT)" Date: Thu, 24 Jul 2025 12:26:35 -0700 Subject: [PATCH 4/9] add environment details --- README.md | 6 +- environment.yml | 218 ++++++++++++++++++++++++++++++++++++++++ octave-requirements.txt | 9 ++ 3 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 environment.yml create mode 100644 octave-requirements.txt diff --git a/README.md b/README.md index 8eecfdca..df9220a4 100644 --- a/README.md +++ b/README.md @@ -38,4 +38,8 @@ A set of tutorial videos introducing aspects of ISETCam and the companion tool f - We have tested `isethdrsensor/scripts/fullSimulation.m` on examples from the ISET HDR dataset. - Known warnings that Octave throws: - Octave can't read `filterNames` from the `.mat` files. As a temporary fix, we've hardcoded r, g, b filter names. - - After the recent updates to `isetcam/main`, Octave throws a new but benign warning "Invalid UTF-8 byte sequences have been replaced." \ No newline at end of file + - After the recent updates to `isetcam/main`, Octave throws a new but benign warning "Invalid UTF-8 byte sequences have been replaced." + +## Instructions for Octave Packages +- Get kernel-level packages for a conda environment from `environment.yml` +- Get packages for Octave as listed in `octave-requirements.txt` diff --git a/environment.yml b/environment.yml new file mode 100644 index 00000000..6ae7e0fb --- /dev/null +++ b/environment.yml @@ -0,0 +1,218 @@ +name: octave-env +channels: + - conda-forge + - defaults +dependencies: + - _libgcc_mutex=0.1 + - _openmp_mutex=4.5 + - _x86_64-microarch-level=4 + - alsa-lib=1.2.14 + - arpack=3.9.1 + - attr=2.5.1 + - binutils=2.44 + - binutils_impl_linux-64=2.44 + - binutils_linux-64=2.44 + - bzip2=1.0.8 + - c-ares=1.34.5 + - c-compiler=1.10.0 + - ca-certificates=2025.7.9 + - cairo=1.18.4 + - curl=8.14.1 + - cxx-compiler=1.10.0 + - cyrus-sasl=2.1.28 + - dbus=1.16.2 + - fftw=3.3.10 + - fltk=1.3.10 + - font-ttf-dejavu-sans-mono=2.37 + - font-ttf-inconsolata=3.000 + - font-ttf-source-code-pro=2.038 + - font-ttf-ubuntu=0.83 + - fontconfig=2.15.0 + - fonts-conda-ecosystem=1 + - fonts-conda-forge=1 + - freetype=2.13.3 + - fribidi=1.0.10 + - gcc=13.3.0 + - gcc_impl_linux-64=13.3.0 + - gcc_linux-64=13.3.0 + - gettext=0.25.1 + - gettext-tools=0.25.1 + - gfortran=13.3.0 + - gfortran_impl_linux-64=13.3.0 + - gfortran_linux-64=13.3.0 + - ghostscript=10.04.0 + - giflib=5.2.2 + - gl2ps=1.4.2 + - glib=2.84.2 + - glib-tools=2.84.2 + - glpk=5.0 + - gmp=6.3.0 + - gnuplot=5.4.10 + - graphicsmagick=1.3.45 + - graphite2=1.3.14 + - gst-plugins-base=1.24.11 + - gstreamer=1.24.11 + - gxx=13.3.0 + - gxx_impl_linux-64=13.3.0 + - gxx_linux-64=13.3.0 + - harfbuzz=11.2.1 + - hdf5=1.14.6 + - icu=75.1 + - imath=3.1.12 + - intel-openmp=2022.0.1 + - kernel-headers_linux-64=3.10.0 + - keyutils=1.6.1 + - krb5=1.21.3 + - lame=3.100 + - ld_impl_linux-64=2.44 + - lerc=4.0.0 + - libaec=1.1.4 + - libamd=3.3.3 + - libasprintf=0.25.1 + - libasprintf-devel=0.25.1 + - libblas=3.9.0 + - libbtf=2.3.2 + - libcamd=3.3.3 + - libcap=2.75 + - libcblas=3.9.0 + - libccolamd=3.3.4 + - libcholmod=5.3.1 + - libclang-cpp20.1=20.1.7 + - libclang13=20.1.7 + - libcolamd=3.3.4 + - libcups=2.3.3 + - libcurl=8.14.1 + - libcxsparse=4.4.1 + - libdeflate=1.24 + - libdrm=2.4.125 + - libedit=3.1.20250104 + - libegl=1.7.0 + - libev=4.33 + - libevent=2.1.12 + - libexpat=2.7.0 + - libffi=3.4.6 + - libflac=1.4.3 + - libfreetype=2.13.3 + - libfreetype6=2.13.3 + - libgcc=15.1.0 + - libgcc-devel_linux-64=13.3.0 + - libgcc-ng=15.1.0 + - libgcrypt-lib=1.11.1 + - libgd=2.3.3 + - libgettextpo=0.25.1 + - libgettextpo-devel=0.25.1 + - libgfortran=15.1.0 + - libgfortran-ng=15.1.0 + - libgfortran5=15.1.0 + - libgl=1.7.0 + - libglib=2.84.2 + - libglu=9.0.3 + - libglvnd=1.7.0 + - libglx=1.7.0 + - libgomp=15.1.0 + - libgpg-error=1.55 + - libiconv=1.18 + - libjpeg-turbo=3.1.0 + - libklu=2.3.5 + - liblapack=3.9.0 + - liblapacke=3.9.0 + - libldl=3.3.2 + - libllvm20=20.1.8 + - liblzma=5.8.1 + - liblzma-devel=5.8.1 + - libmpdec=4.0.0 + - libnghttp2=1.64.0 + - libntlm=1.8 + - libogg=1.3.5 + - libopenblas=0.3.30 + - libopengl=1.7.0 + - libopus=1.5.2 + - libparu=1.0.0 + - libpciaccess=0.18 + - libpng=1.6.50 + - libpq=17.5 + - librbio=4.3.4 + - libsanitizer=13.3.0 + - libsndfile=1.2.2 + - libspex=3.2.3 + - libspqr=4.3.4 + - libsqlite=3.50.2 + - libssh2=1.11.1 + - libstdcxx=15.1.0 + - libstdcxx-devel_linux-64=13.3.0 + - libstdcxx-ng=15.1.0 + - libsuitesparseconfig=7.10.1 + - libsystemd0=257.7 + - libtiff=4.7.0 + - libumfpack=6.3.5 + - libuuid=2.38.1 + - libvorbis=1.3.7 + - libwebp=1.6.0 + - libwebp-base=1.6.0 + - libxcb=1.17.0 + - libxcrypt=4.4.36 + - libxkbcommon=1.10.0 + - libxml2=2.13.8 + - libzlib=1.3.1 + - lz4-c=1.10.0 + - metis=5.1.0 + - mkl=2022.1.0 + - mpfr=4.2.1 + - mpg123=1.32.9 + - ncurses=6.5 + - nspr=4.36 + - nss=3.113 + - octave=9.4.0 + - openexr=3.3.4 + - openldap=2.6.10 + - openssl=3.5.1 + - packaging=25.0 + - pango=1.56.4 + - pcre=8.45 + - pcre2=10.45 + - perl=5.32.1 + - pip=25.1.1 + - pixman=0.46.2 + - ply=3.11 + - portaudio=19.7.0 + - pthread-stubs=0.4 + - pulseaudio-client=17.0 + - pyqt=5.15.11 + - pyqt5-sip=12.17.0 + - python=3.13.5 + - python_abi=3.13 + - qhull=2020.2 + - qscintilla2=2.14.1 + - qt-main=5.15.15 + - readline=8.2 + - setuptools=80.9.0 + - sip=6.10.0 + - suitesparse=7.10.1 + - sundials=7.3.0 + - sysroot_linux-64=2.17 + - texinfo=7.2 + - tk=8.6.13 + - toml=0.10.2 + - tomli=2.2.1 + - tzdata=2025b + - xcb-util=0.4.1 + - xcb-util-image=0.4.0 + - xcb-util-keysyms=0.4.1 + - xcb-util-renderutil=0.3.10 + - xcb-util-wm=0.4.2 + - xkeyboard-config=2.45 + - xorg-libice=1.1.2 + - xorg-libsm=1.2.6 + - xorg-libx11=1.8.12 + - xorg-libxau=1.0.12 + - xorg-libxcomposite=0.4.6 + - xorg-libxdamage=1.1.6 + - xorg-libxdmcp=1.1.5 + - xorg-libxext=1.3.6 + - xorg-libxfixes=6.0.1 + - xorg-libxrender=0.9.12 + - xorg-libxshmfence=1.3.3 + - xorg-libxxf86vm=1.1.6 + - zlib=1.3.1 + - zstd=1.5.7 +prefix: /home/OVT/ayush.jamdar/miniconda3/envs/iset-lfm diff --git a/octave-requirements.txt b/octave-requirements.txt new file mode 100644 index 00000000..606bfb08 --- /dev/null +++ b/octave-requirements.txt @@ -0,0 +1,9 @@ +Package Name | Version +--------------+--------- + control *| 4.1.2 + general *| 2.1.3 + image *| 2.16.1 + io *| 2.7.0 + optiminterp *| 0.3.7 + signal *| 1.4.6 + statistics *| 1.7.4 \ No newline at end of file From 6e4ab8fa96dbed7728d7a0c5e089e0d7a888a8ff Mon Sep 17 00:00:00 2001 From: "Ayush Jamdar (Non-OVT)" Date: Mon, 4 Aug 2025 11:01:33 -0700 Subject: [PATCH 5/9] Added function isOctave() --- README.md | 1 + utility/isOctave.m | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 utility/isOctave.m diff --git a/README.md b/README.md index df9220a4..f2b1cb03 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ A set of tutorial videos introducing aspects of ISETCam and the companion tool f ## Octave Support - July 14, 2025: Ayush Jamdar. +- New: A function `isOctave` tests if code is being run in Octave and uses modified code accordingly. - GNU Octave is an free open-source alternative to MATLAB. While MATLAB (> R2022b) has its own tools to read `exr` files, Octave doesn't have native support for this and relies on other tools like `openexr`. - We have added/modified `exrinfo.cpp`, `exrread.cpp`, `exrreadchannels.cpp`, `exrwrite.cpp`, and `exrwritechannels.cpp` to work with Octave-compatible headers and datatypes. - These readers and writers are completely based on OpenEXR tools. One doesn't need MATLAB to run these scripts. diff --git a/utility/isOctave.m b/utility/isOctave.m new file mode 100644 index 00000000..f7f1b704 --- /dev/null +++ b/utility/isOctave.m @@ -0,0 +1,14 @@ +% Test if running in Octave + +% This function will be called whenever code differs between +% Matlab and Octave, with the goal to extend ISET support + +function retval = isOctave + persistent cacheval; + if isempty (cacheval) + cacheval = (exist ("OCTAVE_VERSION", "builtin") > 0); + end + retval = cacheval; +end + + From 6a977e4269271b5b1b5bf049fe67af9b2992d905 Mon Sep 17 00:00:00 2001 From: "Ayush Jamdar (Non-OVT)" Date: Mon, 4 Aug 2025 11:33:35 -0700 Subject: [PATCH 6/9] Separate make files for Matlab and Octave --- imgproc/openexr/make_matlab.m | 96 +++++++++++++++++++++++++++++++++++ imgproc/openexr/make_octave.m | 60 ++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 imgproc/openexr/make_matlab.m create mode 100644 imgproc/openexr/make_octave.m diff --git a/imgproc/openexr/make_matlab.m b/imgproc/openexr/make_matlab.m new file mode 100644 index 00000000..66bda586 --- /dev/null +++ b/imgproc/openexr/make_matlab.m @@ -0,0 +1,96 @@ +% make.m - Compile OpenEXR MEX functions for MATLAB +% -------------------------------------------------- +% This script builds the C++ MEX wrappers for OpenEXR support in MATLAB. +% It assumes dependencies (OpenEXR, Imath, etc.) are installed in a Conda environment. +% Use the companion `make_octave.m` script to build for Octave. +% +% Modified by Ayush Jamdar, based on ISETCam project code. + +clc; + +% Set verbosity +verbose = false; + +% List of primary source files to compile +build_files = { + 'exrinfo.cpp', ... + 'exrread.cpp', ... + 'exrreadchannels.cpp', ... + 'exrwrite.cpp', ... + 'exrwritechannels.cpp' +}; + +% Companion/shared utility source files +companion_files = { + 'utilities.cpp', ... + 'ImfToMatlab.cpp', ... + 'MatlabToImf.cpp' +}; + +% Extra compiler flags (e.g., verbosity) +additionals = {}; +if verbose + additionals = [additionals, {'-v'}]; +end + +% ------------------------------------------------------------------------ +% ENVIRONMENT CONFIGURATION +% ------------------------------------------------------------------------ + +% Set your Conda environment path here if needed +% Only required if OpenEXR is installed in a specific Conda env +% Change this to match your system/environment +setenv('CONDA_PREFIX', '/home/OVT/ayush.jamdar/miniconda3/envs/openexr_env'); + +% Make sure to run this script *outside* the Conda environment. +% MATLAB's MEX compiler should use system g++ (not conda’s g++) +% You may need to manually select g++: +mex -setup C++ % Choose system compiler, e.g., /usr/bin/g++ + +% ------------------------------------------------------------------------ +% COMPILATION FLAGS +% ------------------------------------------------------------------------ + +% Paths to OpenEXR headers and libraries +conda_prefix = getenv('CONDA_PREFIX'); + +include_paths = { + ['-I', fullfile(conda_prefix, 'include', 'OpenEXR')], ... + ['-I', fullfile(conda_prefix, 'include', 'Imath')] +}; + +lib_path = ['-L', fullfile(conda_prefix, 'lib')]; + +libs = { + '-lOpenEXR', ... + '-lIex', ... + '-lImath', ... + '-lIlmThread', ... + '-lz' +}; + +% ------------------------------------------------------------------------ +% BUILD LOOP +% ------------------------------------------------------------------------ + +[~, which_gpp] = system('which g++'); +disp(['Using g++ at: ', strtrim(which_gpp)]); + +for n = 1:numel(build_files) + if verbose + clc; + end + + file = build_files{n}; + disp(['Building ', file]); + + mex(file, companion_files{:}, ... + include_paths{:}, ... + lib_path, ... + libs{:}, ... + '-largeArrayDims', ... + additionals{:}); +end + +clear; +disp('Finished building OpenEXR for MATLAB'); diff --git a/imgproc/openexr/make_octave.m b/imgproc/openexr/make_octave.m new file mode 100644 index 00000000..04b601f7 --- /dev/null +++ b/imgproc/openexr/make_octave.m @@ -0,0 +1,60 @@ +% make_octave.m - Compile OpenEXR .mex/.oct files for Octave +% ------------------------------------------------------------------- +% This script builds OpenEXR-compatible C++ wrappers using Octave's `mkoctfile`. +% Ensure that your OpenEXR dependencies are installed in a Conda environment. +% +% NOTE: Some C++ header files (e.g., ImfNamespace.h) may be excluded in Octave +% for compatibility. Octave-specific macros (e.g., #ifdef OCTAVE) should be used +% in the C++ source files to handle divergence from MATLAB. +% +% Modified by Ayush Jamdar, based on ISETCam project code. + +clc; +verbose = false; + +% ------------------------------------------------- +build_files = { 'exrinfo.cpp', ... + 'exrread.cpp', ... + 'exrreadchannels.cpp', ... + 'exrwrite.cpp', ... + 'exrwritechannels.cpp'}; + +companion_files = { 'utilities.cpp', ... + 'ImfToMatlab.cpp', ... + 'MatlabToImf.cpp' }; + +% Header and library paths — adjust if needed +conda_prefix = getenv('CONDA_PREFIX'); +if isempty(conda_prefix) + error('CONDA_PREFIX environment variable is not set.'); +end + +include_paths = sprintf('-I%s/include/OpenEXR -I%s/include/Imath', ... + conda_prefix, conda_prefix); +lib_paths = ['-L', fullfile(conda_prefix, 'lib')]; +libs = '-lOpenEXR -lIex -lImath -lIlmThread -lz'; + +% Verbose +extra_flags = ''; +if verbose + extra_flags = '-v'; +end + +% Build loop +for k = 1:numel(build_files) + src = build_files{k}; + [~, outname, ~] = fileparts(src); + out = [outname, '.mex']; + cmd = sprintf('mkoctfile --mex %s %s %s %s %s %s -o %s %s', ... + include_paths, lib_paths, extra_flags, ... + src, strjoin(companion_files, ' '), libs, out); + disp(['Building ', out, '...']); + disp(['CMD: ', cmd]) + status = system(cmd); + if status ~= 0 + error(['Failed to compile: ', src]); + end +end + +clear; +disp('Finished building OpenEXR MEX files for Octave.'); \ No newline at end of file From cbfd600cdad6f33a3aad63bf125eacec4ae62cc1 Mon Sep 17 00:00:00 2001 From: "Ayush Jamdar (Non-OVT)" Date: Mon, 4 Aug 2025 11:34:06 -0700 Subject: [PATCH 7/9] Add isOctave function --- octave-functions/isOctave.m | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 octave-functions/isOctave.m diff --git a/octave-functions/isOctave.m b/octave-functions/isOctave.m new file mode 100644 index 00000000..f7f1b704 --- /dev/null +++ b/octave-functions/isOctave.m @@ -0,0 +1,14 @@ +% Test if running in Octave + +% This function will be called whenever code differs between +% Matlab and Octave, with the goal to extend ISET support + +function retval = isOctave + persistent cacheval; + if isempty (cacheval) + cacheval = (exist ("OCTAVE_VERSION", "builtin") > 0); + end + retval = cacheval; +end + + From f4bcd466c331b17909aadc623fd08a44f6491775 Mon Sep 17 00:00:00 2001 From: "Ayush Jamdar (Non-OVT)" Date: Mon, 4 Aug 2025 11:34:59 -0700 Subject: [PATCH 8/9] Modify makefiles and cpp builders for both Matlab and Octave support --- imgproc/openexr/ImfToMatlab.cpp | 7 ++++- imgproc/openexr/ImfToMatlab.h | 8 +++-- imgproc/openexr/MatlabToImf.h | 11 +++++-- imgproc/openexr/README.md | 1 + imgproc/openexr/exrinfo.cpp | 7 ++++- imgproc/openexr/exrread.cpp | 7 ++++- imgproc/openexr/exrwrite.cpp | 14 +++++++-- imgproc/openexr/make.m | 54 --------------------------------- utility/isOctave.m | 14 --------- 9 files changed, 45 insertions(+), 78 deletions(-) delete mode 100644 imgproc/openexr/make.m delete mode 100644 utility/isOctave.m diff --git a/imgproc/openexr/ImfToMatlab.cpp b/imgproc/openexr/ImfToMatlab.cpp index 6f44a1d5..cb810a87 100644 --- a/imgproc/openexr/ImfToMatlab.cpp +++ b/imgproc/openexr/ImfToMatlab.cpp @@ -24,7 +24,12 @@ #include #include -// #include + +#ifdef OCTAVE + // #include +#else + #include +#endif #ifdef __clang__ #pragma clang diagnostic push diff --git a/imgproc/openexr/ImfToMatlab.h b/imgproc/openexr/ImfToMatlab.h index 3f855400..bc92b6a0 100644 --- a/imgproc/openexr/ImfToMatlab.h +++ b/imgproc/openexr/ImfToMatlab.h @@ -24,10 +24,14 @@ #pragma once #include - -// #include #include +#ifdef OCTAVE + // #include +#else + #include +#endif + // Utilities to convert from OpenEXR types to Matlab types diff --git a/imgproc/openexr/MatlabToImf.h b/imgproc/openexr/MatlabToImf.h index 4fc06bae..558b2371 100644 --- a/imgproc/openexr/MatlabToImf.h +++ b/imgproc/openexr/MatlabToImf.h @@ -306,10 +306,17 @@ inline void convertData(TargetType * dest, switch(srcType) { case mxDOUBLE_CLASS: - convertData(dest, pa, len); + #ifdef OCTAVE + convertData(dest, pa, len); + #else + convertData(dest, pa, len); break; case mxSINGLE_CLASS: - convertData(dest, pa, len); + #ifdef OCTAVE + convertData(dest, pa, len); + #else + convertData(dest, pa, len); + #endif break; case mxINT8_CLASS: convertData(dest, pa, len); diff --git a/imgproc/openexr/README.md b/imgproc/openexr/README.md index ce903a24..61619576 100644 --- a/imgproc/openexr/README.md +++ b/imgproc/openexr/README.md @@ -60,6 +60,7 @@ You may also need to update `~/.matlab/YOUR_MATLAB_VERSION/mexopts.sh` (e.g. in # Octave Support - July 24, 2025: Ayush Jamdar +- New: Added `#ifdef OCTAVE` tests in cpp files. During compile, Octave's `mkoctfile` defines a macro `OCTAVE` automatically. MATLAB does not. - Modified `cpp` files to generate `mex` executables compatible with Octave. - Run `make.m` to generage the executable functions. - The `dev-octave` branch has been tested to work with Octave 6.4.0 diff --git a/imgproc/openexr/exrinfo.cpp b/imgproc/openexr/exrinfo.cpp index e3b0e2da..a0741954 100644 --- a/imgproc/openexr/exrinfo.cpp +++ b/imgproc/openexr/exrinfo.cpp @@ -20,7 +20,12 @@ #include #include #include -// #include // Don't include, not needed in 2.5.7 + +#ifdef OCTAVE + // #include +#else + #include +#endif // Math + exception handling #include diff --git a/imgproc/openexr/exrread.cpp b/imgproc/openexr/exrread.cpp index 16b718d5..51e3eca5 100644 --- a/imgproc/openexr/exrread.cpp +++ b/imgproc/openexr/exrread.cpp @@ -22,7 +22,12 @@ #include "ImfToMatlab.h" #include -// #include + +#ifdef OCTAVE + // #include +#else + #include +#endif #ifdef __clang__ #pragma clang diagnostic push diff --git a/imgproc/openexr/exrwrite.cpp b/imgproc/openexr/exrwrite.cpp index 00057e1d..e7ac45ab 100644 --- a/imgproc/openexr/exrwrite.cpp +++ b/imgproc/openexr/exrwrite.cpp @@ -26,8 +26,17 @@ #include -// #include -// #include // Matlab types + +#ifdef OCTAVE + // #include + // #include // Matlab types + // #include +#else + #include + #include // Matlab types + #include +#endif + #include #include @@ -55,7 +64,6 @@ #include #include #include -// #include #include #include diff --git a/imgproc/openexr/make.m b/imgproc/openexr/make.m deleted file mode 100644 index 1ddafbad..00000000 --- a/imgproc/openexr/make.m +++ /dev/null @@ -1,54 +0,0 @@ -% This makefile generates .mex files using mkoctfile from Octave. -% Some headers from cpp files have been removed / commented out either to avoid conflict -% or absence of those libraries in Octave. -% Thus, we have a compiler for Octave. - -% Modified by Ayush Jamdar. -% Original authors are from the ISETCam project. - -clc; -verbose = false; - -% ------------------------------------------------- -build_files = { 'exrinfo.cpp', ... - 'exrread.cpp', ... - 'exrreadchannels.cpp', ... - 'exrwrite.cpp', ... - 'exrwritechannels.cpp'}; - -% build_files = { 'exrinfo.cpp'}; - -companion_files = { 'utilities.cpp', ... - 'ImfToMatlab.cpp', ... - 'MatlabToImf.cpp' }; - -% Header and library paths — adjust if needed -lib_paths = ['-L', getenv('CONDA_PREFIX'), '/lib']; -include_paths = sprintf('-I%s/include/OpenEXR -I%s/include/Imath', ... - getenv('CONDA_PREFIX'), getenv('CONDA_PREFIX')); -libs = '-lOpenEXR -lIex -lImath -lIlmThread -lz'; - -% Verbose -extra_flags = ''; -if verbose - extra_flags = '-v'; -end - -% Build loop -for k = 1:numel(build_files) - src = build_files{k}; - [~, outname, ~] = fileparts(src); - out = [outname, '.mex']; - cmd = sprintf('mkoctfile --mex %s %s %s %s %s %s -o %s %s', ... - include_paths, lib_paths, extra_flags, ... - src, strjoin(companion_files, ' '), libs, out); - disp(['Building ', out, '...']); - disp(['CMD: ', cmd]) - status = system(cmd); - if status ~= 0 - error(['Failed to compile: ', src]); - end -end - -clear; -disp('Finished building OpenEXR MEX/OCT files for Octave.'); diff --git a/utility/isOctave.m b/utility/isOctave.m deleted file mode 100644 index f7f1b704..00000000 --- a/utility/isOctave.m +++ /dev/null @@ -1,14 +0,0 @@ -% Test if running in Octave - -% This function will be called whenever code differs between -% Matlab and Octave, with the goal to extend ISET support - -function retval = isOctave - persistent cacheval; - if isempty (cacheval) - cacheval = (exist ("OCTAVE_VERSION", "builtin") > 0); - end - retval = cacheval; -end - - From 4fb746f3519adf7c2e89ffdd555b73bd055f314e Mon Sep 17 00:00:00 2001 From: "Ayush Jamdar (Non-OVT)" Date: Mon, 4 Aug 2025 12:03:37 -0700 Subject: [PATCH 9/9] only hardcode filternames if Octave --- octave-functions/README.md | 5 +++-- scene/pattern/sceneHDRLights.m | 20 ++++++++++++++++---- sensor/sensorCreate.m | 21 +++++++++++++++------ utility/dll70/md5/md5.cpp | 6 +++++- 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/octave-functions/README.md b/octave-functions/README.md index e1f90b0b..60509ca9 100644 --- a/octave-functions/README.md +++ b/octave-functions/README.md @@ -1,4 +1,5 @@ ### MATLAB Functions for Octave -This directory hosts custom implementations of MATLAB functions that are otherwise unavailable in Octave. -Note: These functions are written with the help of AI tools and have been tested on ISET examples. \ No newline at end of file +- This directory hosts custom implementations of MATLAB functions that are otherwise unavailable in Octave. +- New: Included an `isOctave` test to keep the code both Matlab and Octave compatible. +Note: Some of these functions are written with the help of AI tools and have been tested on ISET examples. \ No newline at end of file diff --git a/scene/pattern/sceneHDRLights.m b/scene/pattern/sceneHDRLights.m index 50951578..9f2d7ff4 100644 --- a/scene/pattern/sceneHDRLights.m +++ b/scene/pattern/sceneHDRLights.m @@ -54,8 +54,12 @@ xvals = round(linspace(0.2,0.8,nCircles)*imSize); radius = radius*imSize; for ii = 1:numel(xvals) - cc = mod(ii,numel(cColors)) + 1; - img = insertShape(img,'filledcircle',[xvals(ii),y,radius(ii)],'Color',cColors{cc}); + cc = mod(ii,numel(cColors)) + 1; + if isOctave () + img = insertShape(img,'filledcircle',[xvals(ii),y,radius(ii)],'Color',cColors{cc}); + else + img = insertShape(img,'filled-circle',[xvals(ii),y,radius(ii)],'Color',cColors{cc}); + end end %% Put lines of different thickness and orientation around the middle @@ -69,7 +73,11 @@ hw = round([1,7*lineLength; 1,3*lineLength; 3*lineLength,1; 8*lineLength,1]); for ii = 1:numel(xvals) cc = mod(ii,numel(lColors)) + 1; - img = insertShape(img,'filledrectangle',[xvals(ii),y,hw(ii,1),hw(ii,2)],'Color',lColors{cc}); + if isOctave() + img = insertShape(img,'filledrectangle',[xvals(ii),y,hw(ii,1),hw(ii,2)],'Color',lColors{cc}); + else + img = insertShape(img,'filled-rectangle',[xvals(ii),y,hw(ii,1),hw(ii,2)],'Color',lColors{cc}); + end end %% Squares @@ -78,7 +86,11 @@ squareEdge = imSize/64; hw = [2 2; 5 5; 9 9]*squareEdge; for ii = 1:numel(xvals) - img = insertShape(img,'filledrectangle',[xvals(ii),y,hw(ii,1),hw(ii,2)],'Color','white'); + if isOctave() + img = insertShape(img,'filledrectangle',[xvals(ii),y,hw(ii,1),hw(ii,2)],'Color','white'); + else + img = insertShape(img,'filled-rectangle',[xvals(ii),y,hw(ii,1),hw(ii,2)],'Color','white'); + end end % ieNewGraphWin; imagesc(img); axis image diff --git a/sensor/sensorCreate.m b/sensor/sensorCreate.m index d11f1138..85a80b6d 100644 --- a/sensor/sensorCreate.m +++ b/sensor/sensorCreate.m @@ -357,11 +357,16 @@ end qeFile = fullfile(isetRootPath,'data','sensor','colorfilters','OVT','ovt-large.mat'); + wave = sensorGet(sensor, 'wave'); - [data, ~] = ieReadColorFilter(wave, qeFile); - % Hardcoded filter names (since Octave can't read the cell array from .mat) - filterNames = {'r', 'g', 'b'}; + if isOctave() + % Hardcoded filter names (since Octave can't read the cell array from .mat) + [data, ~] = ieReadColorFilter(wave, qeFile); + filterNames = {'r', 'g', 'b'}; + else + [data,filterNames] = ieReadColorFilter(wave,qeFile); + end sensor = sensorSet(sensor, 'filter spectra', data); sensor = sensorSet(sensor, 'filter names', filterNames); @@ -408,10 +413,14 @@ qeFile = fullfile(isetRootPath, 'data', 'sensor', 'colorfilters', 'OVT', 'ovt-large.mat'); wave = sensorGet(sensor, 'wave'); - [data, ~] = ieReadColorFilter(wave, qeFile); - % Hardcoded filter names (since Octave can't read the cell array from .mat) - filterNames = {'r', 'g', 'b'}; + if isOctave() + % Hardcoded filter names (since Octave can't read the cell array from .mat) + [data, ~] = ieReadColorFilter(wave, qeFile); + filterNames = {'r', 'g', 'b'}; + else + [data,filterNames] = ieReadColorFilter(wave,qeFile); + end sensor = sensorSet(sensor, 'filter spectra', data); sensor = sensorSet(sensor, 'filter names', filterNames); diff --git a/utility/dll70/md5/md5.cpp b/utility/dll70/md5/md5.cpp index bfe9965f..d6233a10 100644 --- a/utility/dll70/md5/md5.cpp +++ b/utility/dll70/md5/md5.cpp @@ -60,7 +60,11 @@ char* MD5File(char* szFilename); * */ #include -// #include +#ifdef OCTAVE + // #include +#else + #include +#endif /*********************************************************************