From 07c005ca20309432d9a857a3f4c1f4a5f8ff303f Mon Sep 17 00:00:00 2001 From: Marti Maria Date: Sun, 5 Jun 2022 13:07:27 +0200 Subject: A very preliminar new plug-in on multithreaded transforms This is just the first try to get a new plugin type and a working example. Manuals are still missing. Basically a plug-in of this type adds multicore capabilities. May be used for GPU in future. --- Projects/VC2022/lcms2.sln | Bin 27138 -> 16012 bytes include/lcms2.h | 4 +- include/lcms2_plugin.h | 22 +- plugins/Makefile.am | 2 +- plugins/README.1ST | 2 +- plugins/threaded/COPYING.GPL3 | 674 ++++++++++++++++++ plugins/threaded/Makefile.am | 1 + plugins/threaded/Makefile.in | 649 ++++++++++++++++++ .../Projects/VC2022/lcms2_threaded_plugin.vcxproj | 274 ++++++++ .../VC2022/lcms2_threaded_plugin.vcxproj.filters | 42 ++ .../VC2022/lcms2_threaded_plugin_testbed.vcxproj | 238 +++++++ .../lcms2_threaded_plugin_testbed.vcxproj.filters | 22 + plugins/threaded/include/Makefile.am | 6 + plugins/threaded/include/Makefile.in | 594 ++++++++++++++++ plugins/threaded/include/lcms2_threaded.h | 59 ++ plugins/threaded/src/Makefile.am | 27 + plugins/threaded/src/Makefile.in | 759 +++++++++++++++++++++ plugins/threaded/src/threaded_core.c | 155 +++++ plugins/threaded/src/threaded_internal.h | 79 +++ plugins/threaded/src/threaded_main.c | 43 ++ plugins/threaded/src/threaded_scheduler.c | 108 +++ plugins/threaded/src/threaded_split.c | 204 ++++++ plugins/threaded/testbed/Makefile.am | 23 + plugins/threaded/testbed/Makefile.in | 650 ++++++++++++++++++ plugins/threaded/testbed/test0.icc | Bin 0 -> 568 bytes plugins/threaded/testbed/test1.icc | Bin 0 -> 557536 bytes plugins/threaded/testbed/test2.icc | Bin 0 -> 654496 bytes plugins/threaded/testbed/test3.icc | Bin 0 -> 28484 bytes plugins/threaded/testbed/test5.icc | Bin 0 -> 3240 bytes plugins/threaded/testbed/threaded_testbed.c | 664 ++++++++++++++++++ src/cmserr.c | 45 +- src/cmshalf.c | 2 +- src/cmsplugin.c | 44 +- src/cmsxform.c | 39 ++ src/lcms2_internal.h | 81 ++- testbed/new.icc | Bin 25244 -> 25244 bytes testbed/testbed.exp | Bin 0 -> 61676 bytes testbed/testcms2.c | 4 +- 38 files changed, 5462 insertions(+), 54 deletions(-) create mode 100644 plugins/threaded/COPYING.GPL3 create mode 100644 plugins/threaded/Makefile.am create mode 100644 plugins/threaded/Makefile.in create mode 100644 plugins/threaded/Projects/VC2022/lcms2_threaded_plugin.vcxproj create mode 100644 plugins/threaded/Projects/VC2022/lcms2_threaded_plugin.vcxproj.filters create mode 100644 plugins/threaded/Projects/VC2022/lcms2_threaded_plugin_testbed.vcxproj create mode 100644 plugins/threaded/Projects/VC2022/lcms2_threaded_plugin_testbed.vcxproj.filters create mode 100644 plugins/threaded/include/Makefile.am create mode 100644 plugins/threaded/include/Makefile.in create mode 100644 plugins/threaded/include/lcms2_threaded.h create mode 100644 plugins/threaded/src/Makefile.am create mode 100644 plugins/threaded/src/Makefile.in create mode 100644 plugins/threaded/src/threaded_core.c create mode 100644 plugins/threaded/src/threaded_internal.h create mode 100644 plugins/threaded/src/threaded_main.c create mode 100644 plugins/threaded/src/threaded_scheduler.c create mode 100644 plugins/threaded/src/threaded_split.c create mode 100644 plugins/threaded/testbed/Makefile.am create mode 100644 plugins/threaded/testbed/Makefile.in create mode 100644 plugins/threaded/testbed/test0.icc create mode 100644 plugins/threaded/testbed/test1.icc create mode 100644 plugins/threaded/testbed/test2.icc create mode 100644 plugins/threaded/testbed/test3.icc create mode 100644 plugins/threaded/testbed/test5.icc create mode 100644 plugins/threaded/testbed/threaded_testbed.c create mode 100644 testbed/testbed.exp diff --git a/Projects/VC2022/lcms2.sln b/Projects/VC2022/lcms2.sln index 2c4847f..1c21702 100644 Binary files a/Projects/VC2022/lcms2.sln and b/Projects/VC2022/lcms2.sln differ diff --git a/include/lcms2.h b/include/lcms2.h index 5e0aa33..8e4dd39 100644 --- a/include/lcms2.h +++ b/include/lcms2.h @@ -23,7 +23,7 @@ // //--------------------------------------------------------------------------------- // -// Version 2.13.1 +// Version 2.14 alpha // #ifndef _lcms2_H @@ -81,7 +81,7 @@ extern "C" { #endif // Version/release -#define LCMS_VERSION 2131 +#define LCMS_VERSION 2140 // I will give the chance of redefining basic types for compilers that are not fully C99 compliant #ifndef CMS_BASIC_TYPES_ALREADY_DEFINED diff --git a/include/lcms2_plugin.h b/include/lcms2_plugin.h index 27fdb6a..33540b8 100644 --- a/include/lcms2_plugin.h +++ b/include/lcms2_plugin.h @@ -209,6 +209,7 @@ typedef void* (* _cmsDupUserDataFn)(cmsContext ContextID, const void* Data); #define cmsPluginOptimizationSig 0x6F707448 // 'optH' #define cmsPluginTransformSig 0x7A666D48 // 'xfmH' #define cmsPluginMutexSig 0x6D747A48 // 'mtxH' +#define cmsPluginParalellizationSig 0x70726C48 // 'prlH typedef struct _cmsPluginBaseStruct { @@ -596,7 +597,7 @@ typedef void (* _cmsTransformFn)(struct _cmstransform_struct *CMMcargo, // const void* InputBuffer, void* OutputBuffer, cmsUInt32Number Size, - cmsUInt32Number Stride); // Stride in bytes to the next plana in planar formats + cmsUInt32Number Stride); // Stride in bytes to the next plane in planar formats typedef void (*_cmsTransform2Fn)(struct _cmstransform_struct *CMMcargo, @@ -669,6 +670,25 @@ CMSAPI void CMSEXPORT _cmsDestroyMutex(cmsContext ContextID, void* mtx); CMSAPI cmsBool CMSEXPORT _cmsLockMutex(cmsContext ContextID, void* mtx); CMSAPI void CMSEXPORT _cmsUnlockMutex(cmsContext ContextID, void* mtx); +//---------------------------------------------------------------------------------------------------------- +// Parallelization + +CMSAPI _cmsTransform2Fn CMSEXPORT _cmsGetTransformWorker(struct _cmstransform_struct* CMMcargo); +CMSAPI cmsInt32Number CMSEXPORT _cmsGetTransformMaxWorkers(struct _cmstransform_struct* CMMcargo); +CMSAPI cmsUInt32Number CMSEXPORT _cmsGetTransformWorkerFlags(struct _cmstransform_struct* CMMcargo); + +// Let's plug-in to guess the best number of workers +#define CMS_GUESS_MAX_WORKERS -1 + +typedef struct { + cmsPluginBase base; + + cmsInt32Number MaxWorkers; // Number of starts to do as maximum + cmsUInt32Number WorkerFlags; // Reserved + _cmsTransform2Fn SchedulerFn; // callback to setup functions + +} cmsPluginParalellization; + #ifndef CMS_USE_CPP_API # ifdef __cplusplus diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 3e04f59..ccc078a 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -1 +1 @@ -SUBDIRS = fast_float +SUBDIRS = fast_float threaded diff --git a/plugins/README.1ST b/plugins/README.1ST index c8ab286..ba02de2 100644 --- a/plugins/README.1ST +++ b/plugins/README.1ST @@ -2,5 +2,5 @@ IMPORTANT: Before adding those plug-ins to your commercial project, please check licenses for each plugin. - LittleCMS core is released under MIT, but plug-ins may be released under other license. fast_float, for example is GPL3 + LittleCMS core is released under MIT, but plug-ins may be released under other license. fast_float and threaded are GPL3 \ No newline at end of file diff --git a/plugins/threaded/COPYING.GPL3 b/plugins/threaded/COPYING.GPL3 new file mode 100644 index 0000000..20d40b6 --- /dev/null +++ b/plugins/threaded/COPYING.GPL3 @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/plugins/threaded/Makefile.am b/plugins/threaded/Makefile.am new file mode 100644 index 0000000..625c93b --- /dev/null +++ b/plugins/threaded/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = src include testbed diff --git a/plugins/threaded/Makefile.in b/plugins/threaded/Makefile.in new file mode 100644 index 0000000..4c8da11 --- /dev/null +++ b/plugins/threaded/Makefile.in @@ -0,0 +1,649 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = plugins/fast_float +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/m4/ax_append_compile_flags.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGICC_DEPLIBS = @JPEGICC_DEPLIBS@ +LCMS_LIB_DEPLIBS = @LCMS_LIB_DEPLIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBRARY_AGE = @LIBRARY_AGE@ +LIBRARY_CURRENT = @LIBRARY_CURRENT@ +LIBRARY_REVISION = @LIBRARY_REVISION@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIB_JPEG = @LIB_JPEG@ +LIB_MATH = @LIB_MATH@ +LIB_PLUGINS = @LIB_PLUGINS@ +LIB_THREAD = @LIB_THREAD@ +LIB_TIFF = @LIB_TIFF@ +LIB_ZLIB = @LIB_ZLIB@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TIFFICC_DEPLIBS = @TIFFICC_DEPLIBS@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +inline = @inline@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = src include testbed +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign plugins/fast_float/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign plugins/fast_float/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/plugins/threaded/Projects/VC2022/lcms2_threaded_plugin.vcxproj b/plugins/threaded/Projects/VC2022/lcms2_threaded_plugin.vcxproj new file mode 100644 index 0000000..135a586 --- /dev/null +++ b/plugins/threaded/Projects/VC2022/lcms2_threaded_plugin.vcxproj @@ -0,0 +1,274 @@ + + + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + {71dede59-3f1e-486b-a899-4283000f76b5} + + + + + + + + + + {6A44744B-BED4-49EC-87BB-83978458CE19} + Win32Proj + fast + 10.0 + + + + StaticLibrary + true + Unicode + v143 + + + StaticLibrary + true + Unicode + v143 + + + StaticLibrary + true + Unicode + v143 + + + StaticLibrary + false + true + Unicode + v143 + + + StaticLibrary + false + true + Unicode + v143 + + + StaticLibrary + false + true + Unicode + v143 + + + + + + + + + + + + + + + + + + + + + + + + + AllRules.ruleset + $(Platform)\threaded_plugin_$(Configuration)\ + ..\..\..\..\Lib\MS\ + + + AllRules.ruleset + $(Platform)\threaded_plugin_$(Configuration)\ + + + AllRules.ruleset + $(Platform)\threaded_plugin_$(Configuration)\ + ..\..\..\..\Lib\MS\ + + + $(Platform)\threaded_plugin_$(Configuration)\ + ..\..\..\..\Lib\MS\ + + + $(Platform)\threaded_plugin_$(Configuration)\ + + + $(Platform)\threaded_plugin_$(Configuration)\ + ..\..\..\..\Lib\MS\ + + + + + + Level4 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\include;..\..\..\..\include;%(AdditionalIncludeDirectories) + Fast + + + Windows + true + + + + + + + Level4 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\include;..\..\..\..\include;%(AdditionalIncludeDirectories) + Fast + + + Windows + true + + + + + + + Level4 + Disabled + WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\include;..\..\..\..\include;%(AdditionalIncludeDirectories) + Fast + + + Windows + true + + + + + Level4 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\include;..\..\..\..\include;%(AdditionalIncludeDirectories) + MultiThreaded + false + AnySuitable + Speed + true + true + Fast + true + StreamingSIMDExtensions2 + + + Windows + true + true + true + + + true + + + + + Level4 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\include;..\..\..\..\include;%(AdditionalIncludeDirectories) + MultiThreaded + false + AnySuitable + Speed + true + true + Fast + true + StreamingSIMDExtensions2 + + + Windows + true + true + true + + + true + + + + + Level4 + + + MaxSpeed + true + true + WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\include;..\..\..\..\include;%(AdditionalIncludeDirectories) + MultiThreaded + AnySuitable + Speed + true + true + true + Fast + StreamingSIMDExtensions2 + + + Windows + true + true + true + + + + + + \ No newline at end of file diff --git a/plugins/threaded/Projects/VC2022/lcms2_threaded_plugin.vcxproj.filters b/plugins/threaded/Projects/VC2022/lcms2_threaded_plugin.vcxproj.filters new file mode 100644 index 0000000..c0bad06 --- /dev/null +++ b/plugins/threaded/Projects/VC2022/lcms2_threaded_plugin.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {7d5b1769-2be4-46f2-9e35-6260eea79d7f} + + + {012df308-35db-4909-b035-b1cd5fd1ee5b} + + + + + Header Files + + + Source Files + + + + + doc + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/plugins/threaded/Projects/VC2022/lcms2_threaded_plugin_testbed.vcxproj b/plugins/threaded/Projects/VC2022/lcms2_threaded_plugin_testbed.vcxproj new file mode 100644 index 0000000..eb8dd68 --- /dev/null +++ b/plugins/threaded/Projects/VC2022/lcms2_threaded_plugin_testbed.vcxproj @@ -0,0 +1,238 @@ + + + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {F56B9CBA-A34D-4C68-9003-A6919236399E} + Win32Proj + fast_testbed + 10.0 + + + + Application + true + Unicode + v143 + + + Application + true + Unicode + v143 + + + Application + true + Unicode + v143 + + + Application + false + true + Unicode + v143 + + + Application + false + true + Unicode + v143 + + + Application + false + true + Unicode + v143 + + + + + + + + + + + + + + + + + + + + + + + + + true + $(Platform)\testbed_$(Configuration)\ + $(ProjectDir)..\..\testbed\ + + + true + $(Platform)\testbed_$(Configuration)\ + + + true + $(Platform)\testbed_$(Configuration)\ + $(ProjectDir)..\..\testbed\ + + + false + $(Platform)\testbed_$(Configuration)\ + $(ProjectDir)..\..\testbed\ + + + false + $(Platform)\testbed_$(Configuration)\ + + + false + $(Platform)\testbed_$(Configuration)\ + $(ProjectDir)..\..\testbed\ + + + + + + Level4 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + ..\..\..\..\include;..\..\include;..\..\src + + + Console + true + + + + + + + Level4 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + ..\..\..\..\include;..\..\include;..\..\src + + + Console + true + + + + + + + Level4 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + ..\..\..\..\include;..\..\include;..\..\src + + + Console + true + + + + + Level4 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + ..\..\..\..\include;..\..\include;..\..\src + MultiThreaded + + + Console + true + true + true + + + + + Level4 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + ..\..\..\..\include;..\..\include;..\..\src + MultiThreaded + + + Console + true + true + true + + + + + Level4 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + ..\..\..\..\include;..\..\include;..\..\src + MultiThreaded + + + Console + true + true + true + + + + + {71dede59-3f1e-486b-a899-4283000f76b5} + + + {6a44744b-bed4-49ec-87bb-83978458ce19} + + + + + + + + + \ No newline at end of file diff --git a/plugins/threaded/Projects/VC2022/lcms2_threaded_plugin_testbed.vcxproj.filters b/plugins/threaded/Projects/VC2022/lcms2_threaded_plugin_testbed.vcxproj.filters new file mode 100644 index 0000000..0cba047 --- /dev/null +++ b/plugins/threaded/Projects/VC2022/lcms2_threaded_plugin_testbed.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/plugins/threaded/include/Makefile.am b/plugins/threaded/include/Makefile.am new file mode 100644 index 0000000..7384fea --- /dev/null +++ b/plugins/threaded/include/Makefile.am @@ -0,0 +1,6 @@ +# +# Makefile for include directory + +include_HEADERS = lcms2_threaded.h + +EXTRA_DIST = lcms2_threaded.h diff --git a/plugins/threaded/include/Makefile.in b/plugins/threaded/include/Makefile.in new file mode 100644 index 0000000..9629ed7 --- /dev/null +++ b/plugins/threaded/include/Makefile.in @@ -0,0 +1,594 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# +# Makefile for include directory + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = plugins/fast_float/include +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/m4/ax_append_compile_flags.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(includedir)" +HEADERS = $(include_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGICC_DEPLIBS = @JPEGICC_DEPLIBS@ +LCMS_LIB_DEPLIBS = @LCMS_LIB_DEPLIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBRARY_AGE = @LIBRARY_AGE@ +LIBRARY_CURRENT = @LIBRARY_CURRENT@ +LIBRARY_REVISION = @LIBRARY_REVISION@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIB_JPEG = @LIB_JPEG@ +LIB_MATH = @LIB_MATH@ +LIB_PLUGINS = @LIB_PLUGINS@ +LIB_THREAD = @LIB_THREAD@ +LIB_TIFF = @LIB_TIFF@ +LIB_ZLIB = @LIB_ZLIB@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TIFFICC_DEPLIBS = @TIFFICC_DEPLIBS@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +inline = @inline@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +include_HEADERS = lcms2_fast_float.h +EXTRA_DIST = lcms2_fast_float.h +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign plugins/fast_float/include/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign plugins/fast_float/include/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-includeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-includeHEADERS install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-includeHEADERS + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/plugins/threaded/include/lcms2_threaded.h b/plugins/threaded/include/lcms2_threaded.h new file mode 100644 index 0000000..6bd38be --- /dev/null +++ b/plugins/threaded/include/lcms2_threaded.h @@ -0,0 +1,59 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System, multithread extensions +// Copyright (c) 1998-2022 Marti Maria Saguer, all rights reserved +// +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//--------------------------------------------------------------------------------- + +#ifndef _LCMS2_THREADED_H +#define _LCMS2_THREADED_H + +#include "lcms2_plugin.h" + +#ifdef CMS_NO_PTHREADS +#error "This plug-in needs pthreads to operate" +#endif + +#ifndef CMS_USE_CPP_API +# ifdef __cplusplus +extern "C" { +# endif +#endif + +#define LCMS2_THREADED_VERSION 1000 + +// Configuration toggles + +// The one and only plug-in entry point. To install this plugin in your code you need to place this in +// some initialization place. IOf you want to combine this plug-in with fastfloat, make sure to call +// the threaded entry point comes last in chain. +// +// cmsPlugin(cmsThreadedExtensions(CMS_THREADED_GUESS_MAX_THREADS)); +// + +#define CMS_THREADED_GUESS_MAX_THREADS -1 + +CMSAPI void* CMSEXPORT cmsThreadedExtensions(cmsInt32Number max_threads, cmsUInt32Number flags); + +#ifndef CMS_USE_CPP_API +# ifdef __cplusplus + } +# endif +#endif + +#endif + diff --git a/plugins/threaded/src/Makefile.am b/plugins/threaded/src/Makefile.am new file mode 100644 index 0000000..13420c7 --- /dev/null +++ b/plugins/threaded/src/Makefile.am @@ -0,0 +1,27 @@ +# +# Makefile for building lcms2_threaded plugin +# + +# Don't require all the GNU mandated files +AUTOMAKE_OPTIONS = 1.7 foreign + +includedir = ${prefix}/include + +# Shared libraries built in this directory +lib_LTLIBRARIES = liblcms2_threaded.la + +LIBRARY_CURRENT = 1 +LIBRARY_REVISION = 0 +LIBRARY_AGE = 0 + +AM_CPPFLAGS = -Ofast -I$(top_builddir)/include -I$(top_srcdir)/include -I$(srcdir)/../include -I$(builddir)/../include + +liblcms2_threaded_la_LDFLAGS = -no-undefined \ + -version-info $(LIBRARY_CURRENT):$(LIBRARY_REVISION):$(LIBRARY_AGE) + +liblcms2_threaded_la_LIBADD = $(LCMS_LIB_DEPLIBS) $(top_builddir)/src/liblcms2.la + +liblcms2_threaded_la_SOURCES = threaded_split.c threaded_core.c threaded_main.c threaded_scheduler.c threaded_internal.h + + + diff --git a/plugins/threaded/src/Makefile.in b/plugins/threaded/src/Makefile.in new file mode 100644 index 0000000..f420a00 --- /dev/null +++ b/plugins/threaded/src/Makefile.in @@ -0,0 +1,759 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# +# Makefile for building lcms2_fast_float library +# + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = plugins/fast_float/src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/m4/ax_append_compile_flags.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +liblcms2_fast_float_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(top_builddir)/src/liblcms2.la +am_liblcms2_fast_float_la_OBJECTS = fast_8_curves.lo \ + fast_8_matsh_sse.lo fast_8_matsh.lo fast_8_tethra.lo \ + fast_16_tethra.lo fast_float_15bits.lo fast_float_15mats.lo \ + fast_float_cmyk.lo fast_float_curves.lo fast_float_matsh.lo \ + fast_float_separate.lo fast_float_sup.lo fast_float_tethra.lo \ + fast_float_lab.lo +liblcms2_fast_float_la_OBJECTS = $(am_liblcms2_fast_float_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +liblcms2_fast_float_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(liblcms2_fast_float_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/fast_16_tethra.Plo \ + ./$(DEPDIR)/fast_8_curves.Plo ./$(DEPDIR)/fast_8_matsh.Plo \ + ./$(DEPDIR)/fast_8_matsh_sse.Plo ./$(DEPDIR)/fast_8_tethra.Plo \ + ./$(DEPDIR)/fast_float_15bits.Plo \ + ./$(DEPDIR)/fast_float_15mats.Plo \ + ./$(DEPDIR)/fast_float_cmyk.Plo \ + ./$(DEPDIR)/fast_float_curves.Plo \ + ./$(DEPDIR)/fast_float_lab.Plo \ + ./$(DEPDIR)/fast_float_matsh.Plo \ + ./$(DEPDIR)/fast_float_separate.Plo \ + ./$(DEPDIR)/fast_float_sup.Plo \ + ./$(DEPDIR)/fast_float_tethra.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(liblcms2_fast_float_la_SOURCES) +DIST_SOURCES = $(liblcms2_fast_float_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGICC_DEPLIBS = @JPEGICC_DEPLIBS@ +LCMS_LIB_DEPLIBS = @LCMS_LIB_DEPLIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBRARY_AGE = 0 +LIBRARY_CURRENT = 1 +LIBRARY_REVISION = 1 +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIB_JPEG = @LIB_JPEG@ +LIB_MATH = @LIB_MATH@ +LIB_PLUGINS = @LIB_PLUGINS@ +LIB_THREAD = @LIB_THREAD@ +LIB_TIFF = @LIB_TIFF@ +LIB_ZLIB = @LIB_ZLIB@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TIFFICC_DEPLIBS = @TIFFICC_DEPLIBS@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = ${prefix}/include +infodir = @infodir@ +inline = @inline@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# Don't require all the GNU mandated files +AUTOMAKE_OPTIONS = 1.7 foreign + +# Shared libraries built in this directory +lib_LTLIBRARIES = liblcms2_fast_float.la +AM_CPPFLAGS = -Ofast -I$(top_builddir)/include -I$(top_srcdir)/include -I$(srcdir)/../include -I$(builddir)/../include +liblcms2_fast_float_la_LDFLAGS = -no-undefined \ + -version-info $(LIBRARY_CURRENT):$(LIBRARY_REVISION):$(LIBRARY_AGE) + +liblcms2_fast_float_la_LIBADD = $(LCMS_LIB_DEPLIBS) $(top_builddir)/src/liblcms2.la +liblcms2_fast_float_la_SOURCES = fast_8_curves.c fast_8_matsh_sse.c fast_8_matsh.c fast_8_tethra.c \ + fast_16_tethra.c fast_float_15bits.c fast_float_15mats.c fast_float_cmyk.c fast_float_curves.c fast_float_matsh.c \ + fast_float_separate.c fast_float_sup.c fast_float_tethra.c fast_float_lab.c fast_float_internal.h + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign plugins/fast_float/src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign plugins/fast_float/src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +liblcms2_fast_float.la: $(liblcms2_fast_float_la_OBJECTS) $(liblcms2_fast_float_la_DEPENDENCIES) $(EXTRA_liblcms2_fast_float_la_DEPENDENCIES) + $(AM_V_CCLD)$(liblcms2_fast_float_la_LINK) -rpath $(libdir) $(liblcms2_fast_float_la_OBJECTS) $(liblcms2_fast_float_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fast_16_tethra.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fast_8_curves.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fast_8_matsh.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fast_8_matsh_sse.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fast_8_tethra.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fast_float_15bits.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fast_float_15mats.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fast_float_cmyk.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fast_float_curves.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fast_float_lab.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fast_float_matsh.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fast_float_separate.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fast_float_sup.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fast_float_tethra.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/fast_16_tethra.Plo + -rm -f ./$(DEPDIR)/fast_8_curves.Plo + -rm -f ./$(DEPDIR)/fast_8_matsh.Plo + -rm -f ./$(DEPDIR)/fast_8_matsh_sse.Plo + -rm -f ./$(DEPDIR)/fast_8_tethra.Plo + -rm -f ./$(DEPDIR)/fast_float_15bits.Plo + -rm -f ./$(DEPDIR)/fast_float_15mats.Plo + -rm -f ./$(DEPDIR)/fast_float_cmyk.Plo + -rm -f ./$(DEPDIR)/fast_float_curves.Plo + -rm -f ./$(DEPDIR)/fast_float_lab.Plo + -rm -f ./$(DEPDIR)/fast_float_matsh.Plo + -rm -f ./$(DEPDIR)/fast_float_separate.Plo + -rm -f ./$(DEPDIR)/fast_float_sup.Plo + -rm -f ./$(DEPDIR)/fast_float_tethra.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/fast_16_tethra.Plo + -rm -f ./$(DEPDIR)/fast_8_curves.Plo + -rm -f ./$(DEPDIR)/fast_8_matsh.Plo + -rm -f ./$(DEPDIR)/fast_8_matsh_sse.Plo + -rm -f ./$(DEPDIR)/fast_8_tethra.Plo + -rm -f ./$(DEPDIR)/fast_float_15bits.Plo + -rm -f ./$(DEPDIR)/fast_float_15mats.Plo + -rm -f ./$(DEPDIR)/fast_float_cmyk.Plo + -rm -f ./$(DEPDIR)/fast_float_curves.Plo + -rm -f ./$(DEPDIR)/fast_float_lab.Plo + -rm -f ./$(DEPDIR)/fast_float_matsh.Plo + -rm -f ./$(DEPDIR)/fast_float_separate.Plo + -rm -f ./$(DEPDIR)/fast_float_sup.Plo + -rm -f ./$(DEPDIR)/fast_float_tethra.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/plugins/threaded/src/threaded_core.c b/plugins/threaded/src/threaded_core.c new file mode 100644 index 0000000..88f617b --- /dev/null +++ b/plugins/threaded/src/threaded_core.c @@ -0,0 +1,155 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System, multithread extensions +// Copyright (c) 1998-2022 Marti Maria Saguer, all rights reserved +// +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//--------------------------------------------------------------------------------- + +#include "threaded_internal.h" + +// This is the threading support. Unfortunately, it has to be platform-dependent because +// windows does not support pthreads. +#ifdef CMS_IS_WINDOWS_ + +#define WIN32_LEAN_AND_MEAN 1 +#include + +// To pass parameter to the thread +typedef struct +{ + _cmsTransform2Fn worker; + _cmsWorkSlice* param; + +} thread_adaptor_param; + + +// This is an adaptor to the native thread on windows +static +DWORD WINAPI thread_adaptor(LPVOID p) +{ + thread_adaptor_param* ap = (thread_adaptor_param*)p; + _cmsWorkSlice* s = ap->param; + + ap->worker(s->CMMcargo, s->InputBuffer, s->OutputBuffer, + s->PixelsPerLine, s->LineCount, s->Stride); + _cmsFree(0, p); + return 0; +} + +// This function creates a thread and executes it. The thread calls the worker function +// with the given parameters. +cmsHANDLE _cmsThrCreateWorker(cmsContext ContextID, _cmsTransform2Fn worker, _cmsWorkSlice* param) +{ + DWORD ThreadID; + thread_adaptor_param* p; + HANDLE handle; + + p = (thread_adaptor_param*)_cmsMalloc(0, sizeof(thread_adaptor_param)); + if (p == NULL) return NULL; + + p->worker = worker; + p->param = param; + + handle = CreateThread(NULL, 0, thread_adaptor, (LPVOID) p, 0, &ThreadID); + if (handle == NULL) + { + cmsSignalError(ContextID, cmsERROR_UNDEFINED, "Cannot create thread"); + } + + return (cmsHANDLE)handle; +} + +// Waits until given thread is ended +void _cmsThrJoinWorker(cmsContext ContextID, cmsHANDLE hWorker) +{ + if (WaitForSingleObject((HANDLE)hWorker, INFINITE) != WAIT_OBJECT_0) + { + cmsSignalError(ContextID, cmsERROR_UNDEFINED, "Cannot join thread"); + } +} + +// Returns the ideal number of threads the system can run +cmsInt32Number _cmsThrIdealThreadCount(void) +{ + SYSTEM_INFO sysinfo; + + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; //Returns the number of processors in the system. +} + +#else + +// Rest of the wide world +#include +#include + +// To pass parameter to the thread +typedef struct +{ + _cmsTransform2Fn worker; + _cmsWorkSlice* param; + +} thread_adaptor_param; + + +// This is the native thread on pthread +static +void thread_adaptor(void* p) +{ + thread_adaptor_param* ap = (thread_adaptor_param*)p; + _cmsWorkSlice* s = ap->param; + + ap->worker(s->CMMcargo, s->InputBuffer, s->OutputBuffer, + s->PixelsPerLine, s->LineCount, &s->Stride); +} + +// This function creates a thread and executes it. The thread calls the worker function +// with the given parameters. +cmsHANDLE _cmsThrCreateWorker(cmsContext ContextID, _cmsTransform2Fn worker, _cmsWorkSlice* param) +{ + pthread_t threadId; + + int err = pthread_create(&threadId, NULL, thread_adaptor, param); + if (err != 0) + { + cmsSignalError(ContextID, cmsERROR_UNDEFINED, "Cannot create thread [pthread error %d]", err); + return NULL; + } + else + return (cmsHANDLE) threadId; +} + +// Waits until given thread is ended +void _cmsThrJoinWorker(cmsContext ContextID, cmsHANDLE hWorker) +{ + int err = pthread_join((pthread_t)hWorker, NULL); + if (err != 0) + { + cmsSignalError(ContextID, cmsERROR_UNDEFINED, "Cannot join thread [pthread error %d]", err); + } +} + +cmsInt32Number _cmsThrIdealThreadCount(void) +{ + long cores = sysconf(_SC_NPROCESSORS_ONLN); + if (cores == -1L) + return 1; + else + return (cmsInt32Number)cores; +} + +#endif diff --git a/plugins/threaded/src/threaded_internal.h b/plugins/threaded/src/threaded_internal.h new file mode 100644 index 0000000..e5dc9ff --- /dev/null +++ b/plugins/threaded/src/threaded_internal.h @@ -0,0 +1,79 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System, multithreaded extensions +// Copyright (c) 1998-2022 Marti Maria Saguer, all rights reserved +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//--------------------------------------------------------------------------------- + +#ifndef _THREADED_INTERNAL_H +#define _THREADED_INTERNAL_H + +#include "lcms2_threaded.h" + +// This plugin requires lcms 2.14 or greater +#define REQUIRED_LCMS_VERSION 2140 + +// Unused parameter warning suppression +#define UNUSED_PARAMETER(x) ((void)x) + +// For testbed +#define CMSCHECKPOINT CMSAPI + +// The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999). +// unfortunately VisualC++ does not conform that +#if defined(_MSC_VER) || defined(__BORLANDC__) +# define cmsINLINE __inline +#else +# define cmsINLINE static inline +#endif + +// Holds all parameters for a threadable transform fragment +typedef struct { + + struct _cmstransform_struct* CMMcargo; + + const void* InputBuffer; + void* OutputBuffer; + + cmsUInt32Number PixelsPerLine; + cmsUInt32Number LineCount; + const cmsStride* Stride; + +} _cmsWorkSlice; + +// Count the number of threads needed for this job +cmsUInt32Number _cmsThrCountSlices(struct _cmstransform_struct* CMMcargo, cmsInt32Number MaxWorkers, + cmsUInt32Number PixelsPerLine, cmsUInt32Number LineCount, + cmsStride* Stride); + +// Split work following several expert rules +cmsBool _cmsThrSplitWork(const _cmsWorkSlice* master, cmsInt32Number nslices, _cmsWorkSlice slices[]); + +// Thread primitives +cmsHANDLE _cmsThrCreateWorker(cmsContext ContextID, _cmsTransform2Fn worker, _cmsWorkSlice* param); +void _cmsThrJoinWorker(cmsContext ContextID, cmsHANDLE hWorker); +cmsInt32Number _cmsThrIdealThreadCount(void); + +// The scheduler +void _cmsThrScheduler(struct _cmstransform_struct* CMMcargo, + const void* InputBuffer, + void* OutputBuffer, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + const cmsStride* Stride); +#endif + + diff --git a/plugins/threaded/src/threaded_main.c b/plugins/threaded/src/threaded_main.c new file mode 100644 index 0000000..e11eec6 --- /dev/null +++ b/plugins/threaded/src/threaded_main.c @@ -0,0 +1,43 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System, fast floating point extensions +// Copyright (c) 1998-2022 Marti Maria Saguer, all rights reserved +// +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//--------------------------------------------------------------------------------- + + +#include "threaded_internal.h" + +// The Plug-in entry point +static cmsPluginParalellization Plugin = { + + { cmsPluginMagicNumber, REQUIRED_LCMS_VERSION, cmsPluginParalellizationSig, NULL }, + + CMS_THREADED_GUESS_MAX_THREADS, + 0, + _cmsThrScheduler +}; + +// This is the main plug-in installer. +void* CMSEXPORT cmsThreadedExtensions(cmsInt32Number max_threads, cmsUInt32Number flags) +{ + Plugin.MaxWorkers = max_threads; + Plugin.WorkerFlags = flags; + + return (void*)&Plugin; +} + diff --git a/plugins/threaded/src/threaded_scheduler.c b/plugins/threaded/src/threaded_scheduler.c new file mode 100644 index 0000000..6c54076 --- /dev/null +++ b/plugins/threaded/src/threaded_scheduler.c @@ -0,0 +1,108 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System, multithreaded extensions +// Copyright (c) 1998-2022 Marti Maria Saguer, all rights reserved +// +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//--------------------------------------------------------------------------------- + +#include "threaded_internal.h" + +// The scheduler is responsible to split the work in several portions in a way that each +// portion can be calculated by a different thread. All loacking is already done by lcms +// mutexes, and memory should not overlap. +void _cmsThrScheduler(struct _cmstransform_struct* CMMcargo, + const void* InputBuffer, + void* OutputBuffer, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + const cmsStride* Stride) +{ + cmsContext ContextID = cmsGetTransformContextID(CMMcargo); + _cmsTransform2Fn worker = _cmsGetTransformWorker(CMMcargo); + cmsInt32Number MaxWorkers = _cmsGetTransformMaxWorkers(CMMcargo); + + // flags are not actually being used + // cmsUInt32Number flags = _cmsGetTransformWorkerFlags(CMMcargo); + + _cmsWorkSlice master; + _cmsWorkSlice* slices; + cmsStride FixedStride = *Stride; + cmsHANDLE* handles; + + // Count the number of threads needed for this job. MaxWorkers is the upper limit or -1 to auto + cmsUInt32Number nSlices = _cmsThrCountSlices(CMMcargo, MaxWorkers, PixelsPerLine, LineCount, &FixedStride); + + // Abort early if no threaded code + if (nSlices <= 1) { + + worker(CMMcargo, InputBuffer, OutputBuffer, PixelsPerLine, LineCount, Stride); + return; + } + + // Setup master thread + master.CMMcargo = CMMcargo; + master.InputBuffer = InputBuffer; + master.OutputBuffer = OutputBuffer; + master.PixelsPerLine = PixelsPerLine; + master.LineCount = LineCount; + master.Stride = &FixedStride; + + // Create memory for the slices + slices = (_cmsWorkSlice*)_cmsCalloc(ContextID, nSlices, sizeof(_cmsWorkSlice)); + handles = (cmsHANDLE*) _cmsCalloc(ContextID, nSlices, sizeof(cmsHANDLE)); + + if (slices == NULL || handles == NULL) + { + if (slices) _cmsFree(ContextID, slices); + if (handles) _cmsFree(ContextID, handles); + + // Out of memory in this case only can come from a corruption, but we do the work anyway + worker(CMMcargo, InputBuffer, OutputBuffer, PixelsPerLine, LineCount, Stride); + return; + } + + // All seems ok so far + if (_cmsThrSplitWork(&master, nSlices, slices)) + { + // Work is splitted. Create threads + cmsUInt32Number i; + + for (i = 1; i < nSlices; i++) + { + handles[i] = _cmsThrCreateWorker(ContextID, worker, &slices[i]); + } + + // Do our portion of work + worker(CMMcargo, slices[0].InputBuffer, slices[0].OutputBuffer, + slices[0].PixelsPerLine, slices[0].LineCount, slices[0].Stride); + + // Wait until all threads are finished + for (i = 1; i < nSlices; i++) + { + _cmsThrJoinWorker(ContextID, handles[i]); + } + } + else + { + // Not able to split the work, so don't thread + worker(CMMcargo, InputBuffer, OutputBuffer, PixelsPerLine, LineCount, Stride); + } + + _cmsFree(ContextID, slices); + _cmsFree(ContextID, handles); +} + diff --git a/plugins/threaded/src/threaded_split.c b/plugins/threaded/src/threaded_split.c new file mode 100644 index 0000000..26a2ce2 --- /dev/null +++ b/plugins/threaded/src/threaded_split.c @@ -0,0 +1,204 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System, fast floating point extensions +// Copyright (c) 1998-2022 Marti Maria Saguer, all rights reserved +// +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//--------------------------------------------------------------------------------- + + +#include "threaded_internal.h" + + +// Returns true component size +cmsINLINE cmsUInt32Number ComponentSize(cmsUInt32Number format) +{ + cmsUInt32Number BytesPerComponent = T_BYTES(format); + + // For double, the T_BYTES field is zero + if (BytesPerComponent == 0) + BytesPerComponent = sizeof(cmsUInt64Number); + + return BytesPerComponent; +} + +// Returns bytes from one pixel to the next +cmsINLINE cmsUInt32Number PixelSpacing(cmsUInt32Number format) +{ + if (T_PLANAR(format)) + return ComponentSize(format); + else + return ComponentSize(format) * (T_CHANNELS(format) + T_EXTRA(format)); +} + + +// Memory of block depends of planar or chunky. If lines is 1, then the stride does not contain +// information and we have to calculate the size. If lines > 1, then we can take line size from stride. +// if planar, total memory is number of planes per plane stride. If chunky memory is number of lines per +// line size. If line size is zero, then it should be computed. +static +cmsUInt32Number MemSize(cmsUInt32Number format, + cmsUInt32Number PixelsPerLine, + cmsUInt32Number LineCount, + cmsUInt32Number* BytesPerLine, + cmsUInt32Number BytesPerPlane) +{ + if (T_PLANAR(format)) { + + if (*BytesPerLine == 0) { + + *BytesPerLine = ComponentSize(format) * PixelsPerLine; + } + + return (T_CHANNELS(format) + T_EXTRA(format)) * BytesPerPlane; + } + else + { + if (*BytesPerLine == 0) { + + *BytesPerLine = ComponentSize(format) * (T_CHANNELS(format) + T_EXTRA(format)) * PixelsPerLine; + } + + return LineCount * *BytesPerLine; + } +} + +// Compute how many workers to use. Repairs Stride if any missing member +cmsUInt32Number _cmsThrCountSlices(struct _cmstransform_struct* CMMcargo, cmsInt32Number MaxWorkers, + cmsUInt32Number PixelsPerLine, cmsUInt32Number LineCount, + cmsStride* Stride) +{ + cmsInt32Number MaxInputMem, MaxOutputMem; + cmsInt32Number WorkerCount; + + cmsInt32Number MaxCPUs = _cmsThrIdealThreadCount(); + + if (MaxWorkers == CMS_THREADED_GUESS_MAX_THREADS) { + MaxWorkers = MaxCPUs; + } + else + { + // We allow large number of threads, but this is not going to work well. Warn it. + if (MaxWorkers > MaxCPUs) { + cmsSignalError(NULL, cmsERROR_RANGE, + "Warning: too many threads for actual processor (CPUs=%s, asked=%d)", MaxCPUs, MaxWorkers); + } + } + + MaxInputMem = MemSize(cmsGetTransformInputFormat((cmsHTRANSFORM)CMMcargo), + PixelsPerLine, LineCount, &Stride->BytesPerLineIn, Stride->BytesPerPlaneIn); + + MaxOutputMem = MemSize(cmsGetTransformOutputFormat((cmsHTRANSFORM)CMMcargo), + PixelsPerLine, LineCount, &Stride->BytesPerLineOut, Stride->BytesPerPlaneOut); + + // Each thread takes 128K at least + WorkerCount = (MaxInputMem + MaxOutputMem) / (128 * 1024); + + if (WorkerCount < 1) + WorkerCount = 1; + else + if (WorkerCount > MaxWorkers) + WorkerCount = MaxWorkers; + + return WorkerCount; +} + +// Slice input, output for lines +static +void SlicePerLines(const _cmsWorkSlice* master, cmsInt32Number nslices, + cmsInt32Number LinesPerSlice, _cmsWorkSlice slices[]) +{ + cmsInt32Number i; + cmsInt32Number TotalLines = master ->LineCount; + + for (i = 0; i < nslices; i++) { + + const cmsUInt8Number* PtrInput = master->InputBuffer; + cmsUInt8Number* PtrOutput = master->OutputBuffer; + + cmsInt32Number lines = min(LinesPerSlice, TotalLines); + + memcpy(&slices[i], master, sizeof(_cmsWorkSlice)); + + slices[i].InputBuffer = PtrInput + i * LinesPerSlice * master->Stride->BytesPerLineIn; + slices[i].OutputBuffer = PtrOutput + i * LinesPerSlice * master->Stride->BytesPerLineOut; + + slices[i].LineCount = lines; + TotalLines -= lines; + } +} + +// Per pixels on big blocks of one line +static +void SlicePerPixels(const _cmsWorkSlice* master, cmsInt32Number nslices, + cmsInt32Number PixelsPerSlice, _cmsWorkSlice slices[]) +{ + cmsInt32Number i; + cmsInt32Number TotalPixels = master->PixelsPerLine; // As this works on one line only + + cmsUInt32Number PixelSpacingIn = PixelSpacing(cmsGetTransformInputFormat((cmsHTRANSFORM)master->CMMcargo)); + cmsUInt32Number PixelSpacingOut = PixelSpacing(cmsGetTransformOutputFormat((cmsHTRANSFORM)master->CMMcargo)); + + for (i = 0; i < nslices; i++) { + + const cmsUInt8Number* PtrInput = master->InputBuffer; + cmsUInt8Number* PtrOutput = master->OutputBuffer; + + cmsInt32Number pixels = min(PixelsPerSlice, TotalPixels); + + memcpy(&slices[i], master, sizeof(_cmsWorkSlice)); + + slices[i].InputBuffer = PtrInput + i * PixelsPerSlice * PixelSpacingIn; + slices[i].OutputBuffer = PtrOutput + i * PixelsPerSlice * PixelSpacingOut; + slices[i].PixelsPerLine = pixels; + + TotalPixels -= pixels; + } +} + + +// If multiline, assign a number of lines to each thread. This works on chunky and planar. Stride parameters +// are not changed. In the case of one line, stride chunky is not used and stride planar keeps same. +cmsBool _cmsThrSplitWork(const _cmsWorkSlice* master, cmsInt32Number nslices, _cmsWorkSlice slices[]) +{ + + // Check parameters + if (master->PixelsPerLine == 0 || + master->Stride->BytesPerLineIn == 0 || + master->Stride->BytesPerLineOut == 0) return FALSE; + + // Do the splitting depending on lines + if (master->LineCount <= 1) { + + cmsInt32Number PixelsPerWorker = master->PixelsPerLine / nslices; + + if (PixelsPerWorker <= 0) + return FALSE; + else + SlicePerPixels(master, nslices, PixelsPerWorker, slices); + } + else { + + cmsInt32Number LinesPerWorker = master->LineCount / nslices; + + if (LinesPerWorker <= 0) + return FALSE; + else + SlicePerLines(master, nslices, LinesPerWorker, slices); + } + + return TRUE; +} \ No newline at end of file diff --git a/plugins/threaded/testbed/Makefile.am b/plugins/threaded/testbed/Makefile.am new file mode 100644 index 0000000..8ddd7cd --- /dev/null +++ b/plugins/threaded/testbed/Makefile.am @@ -0,0 +1,23 @@ +# +# Makefile for building threaded_testbed +# + +# Don't require all the GNU mandated files +AUTOMAKE_OPTIONS = 1.7 foreign + +AM_CPPFLAGS = -I$(builddir)/../include -I$(srcdir)/../include -I$(srcdir)/../src \ + -I$(top_builddir)/include + +check_PROGRAMS = threaded_testbed + +threaded_testbed_LDADD = $(builddir)/../src/liblcms2_threaded.la $(LCMS_LIB_DEPLIBS) +threaded_testbed_LDFLAGS = -static @LDFLAGS@ +threaded_testbed_SOURCES = threaded_testbed.c + +EXTRA_DIST = test0.icc test1.icc test2.icc test3.icc test5.icc + +check: + if [ "x$(srcdir)" != "x$(builddir)" ]; then \ + cp $(srcdir)/test?.icc . ; \ + fi + ./threaded_testbed diff --git a/plugins/threaded/testbed/Makefile.in b/plugins/threaded/testbed/Makefile.in new file mode 100644 index 0000000..eec2fad --- /dev/null +++ b/plugins/threaded/testbed/Makefile.in @@ -0,0 +1,650 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# +# Makefile for building fast_float_testbed +# +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = fast_float_testbed$(EXEEXT) +subdir = plugins/fast_float/testbed +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ + $(top_srcdir)/m4/ax_append_compile_flags.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4/ax_require_defined.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am_fast_float_testbed_OBJECTS = fast_float_testbed.$(OBJEXT) +fast_float_testbed_OBJECTS = $(am_fast_float_testbed_OBJECTS) +am__DEPENDENCIES_1 = +fast_float_testbed_DEPENDENCIES = \ + $(builddir)/../src/liblcms2_fast_float.la \ + $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +fast_float_testbed_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(fast_float_testbed_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/fast_float_testbed.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(fast_float_testbed_SOURCES) +DIST_SOURCES = $(fast_float_testbed_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGICC_DEPLIBS = @JPEGICC_DEPLIBS@ +LCMS_LIB_DEPLIBS = @LCMS_LIB_DEPLIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBRARY_AGE = @LIBRARY_AGE@ +LIBRARY_CURRENT = @LIBRARY_CURRENT@ +LIBRARY_REVISION = @LIBRARY_REVISION@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LIB_JPEG = @LIB_JPEG@ +LIB_MATH = @LIB_MATH@ +LIB_PLUGINS = @LIB_PLUGINS@ +LIB_THREAD = @LIB_THREAD@ +LIB_TIFF = @LIB_TIFF@ +LIB_ZLIB = @LIB_ZLIB@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TIFFICC_DEPLIBS = @TIFFICC_DEPLIBS@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +acx_pthread_config = @acx_pthread_config@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +inline = @inline@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# Don't require all the GNU mandated files +AUTOMAKE_OPTIONS = 1.7 foreign +AM_CPPFLAGS = -I$(builddir)/../include -I$(srcdir)/../include -I$(srcdir)/../src \ + -I$(top_builddir)/include + +fast_float_testbed_LDADD = $(builddir)/../src/liblcms2_fast_float.la $(LCMS_LIB_DEPLIBS) +fast_float_testbed_LDFLAGS = -static @LDFLAGS@ +fast_float_testbed_SOURCES = fast_float_testbed.c +EXTRA_DIST = test0.icc test1.icc test2.icc test3.icc test5.icc +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign plugins/fast_float/testbed/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign plugins/fast_float/testbed/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +fast_float_testbed$(EXEEXT): $(fast_float_testbed_OBJECTS) $(fast_float_testbed_DEPENDENCIES) $(EXTRA_fast_float_testbed_DEPENDENCIES) + @rm -f fast_float_testbed$(EXEEXT) + $(AM_V_CCLD)$(fast_float_testbed_LINK) $(fast_float_testbed_OBJECTS) $(fast_float_testbed_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fast_float_testbed.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/fast_float_testbed.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/fast_float_testbed.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +check: + if [ "x$(srcdir)" != "x$(builddir)" ]; then \ + cp $(srcdir)/test?.icc . ; \ + fi + ./fast_float_testbed + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/plugins/threaded/testbed/test0.icc b/plugins/threaded/testbed/test0.icc new file mode 100644 index 0000000..c233a53 Binary files /dev/null and b/plugins/threaded/testbed/test0.icc differ diff --git a/plugins/threaded/testbed/test1.icc b/plugins/threaded/testbed/test1.icc new file mode 100644 index 0000000..d0245c8 Binary files /dev/null and b/plugins/threaded/testbed/test1.icc differ diff --git a/plugins/threaded/testbed/test2.icc b/plugins/threaded/testbed/test2.icc new file mode 100644 index 0000000..73f1b5a Binary files /dev/null and b/plugins/threaded/testbed/test2.icc differ diff --git a/plugins/threaded/testbed/test3.icc b/plugins/threaded/testbed/test3.icc new file mode 100644 index 0000000..d0e7930 Binary files /dev/null and b/plugins/threaded/testbed/test3.icc differ diff --git a/plugins/threaded/testbed/test5.icc b/plugins/threaded/testbed/test5.icc new file mode 100644 index 0000000..34583ab Binary files /dev/null and b/plugins/threaded/testbed/test5.icc differ diff --git a/plugins/threaded/testbed/threaded_testbed.c b/plugins/threaded/testbed/threaded_testbed.c new file mode 100644 index 0000000..e148f82 --- /dev/null +++ b/plugins/threaded/testbed/threaded_testbed.c @@ -0,0 +1,664 @@ +//--------------------------------------------------------------------------------- +// +// Little Color Management System, multithreaded extensions +// Copyright (c) 1998-2022 Marti Maria Saguer, all rights reserved +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//--------------------------------------------------------------------------------- + +#include "threaded_internal.h" + +#include +#include + +// A fast way to convert from/to 16 <-> 8 bits +#define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb)) +#define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((rgb) * 65281 + 8388608) >> 24) & 0xFF) + +// Some pixel representations +typedef struct { cmsUInt8Number r, g, b; } Scanline_rgb8bits; +typedef struct { cmsUInt8Number r, g, b, a; } Scanline_rgba8bits; +typedef struct { cmsUInt8Number c, m, y, k; } Scanline_cmyk8bits; +typedef struct { cmsUInt16Number r, g, b; } Scanline_rgb16bits; +typedef struct { cmsUInt16Number r, g, b, a; } Scanline_rgba16bits; +typedef struct { cmsUInt16Number c, m, y, k; } Scanline_cmyk16bits; + + +// A flushed printf +static +void trace(const char* frm, ...) +{ + va_list args; + + va_start(args, frm); + vfprintf(stderr, frm, args); + fflush(stderr); + va_end(args); +} + + +// The callback function used by cmsSetLogErrorHandler() +static +void FatalErrorQuit(cmsContext ContextID, cmsUInt32Number ErrorCode, const char *Text) +{ + UNUSED_PARAMETER(ContextID); + UNUSED_PARAMETER(ErrorCode); + + trace("** Fatal error: %s\n", Text); + exit(1); +} + +// Rise an error and exit +static +void Fail(const char* frm, ...) +{ + char ReasonToFailBuffer[1024]; + va_list args; + + va_start(args, frm); + vsprintf(ReasonToFailBuffer, frm, args); + FatalErrorQuit(0, 0, ReasonToFailBuffer); + + // unreachable va_end(args); +} + + +// Creates a fake profile that only has a curve. Used in several places +static +cmsHPROFILE CreateCurves(void) +{ + cmsToneCurve* Gamma = cmsBuildGamma(0, 1.1); + cmsToneCurve* Transfer[3]; + cmsHPROFILE h; + + Transfer[0] = Transfer[1] = Transfer[2] = Gamma; + h = cmsCreateLinearizationDeviceLink(cmsSigRgbData, Transfer); + + cmsFreeToneCurve(Gamma); + + return h; +} + + +// -------------------------------------------------------------------------------------------------- +// A C C U R A C Y C H E C K S +// -------------------------------------------------------------------------------------------------- + + + +// Check change format feature +static +void CheckChangeFormat(void) +{ + cmsHPROFILE hsRGB, hLab; + cmsHTRANSFORM xform; + cmsUInt8Number rgb8[3] = { 10, 120, 40 }; + cmsUInt16Number rgb16[3] = { 10* 257, 120*257, 40*257 }; + cmsUInt16Number lab16_1[3], lab16_2[3]; + + trace("Checking change format feature..."); + + hsRGB = cmsCreate_sRGBProfile(); + hLab = cmsCreateLab4Profile(NULL); + + xform = cmsCreateTransform(hsRGB, TYPE_RGB_16, hLab, TYPE_Lab_16, INTENT_PERCEPTUAL, 0); + + cmsCloseProfile(hsRGB); + cmsCloseProfile(hLab); + + cmsDoTransform(xform, rgb16, lab16_1, 1); + + cmsChangeBuffersFormat(xform, TYPE_RGB_8, TYPE_Lab_16); + + cmsDoTransform(xform, rgb8, lab16_2, 1); + cmsDeleteTransform(xform); + + if (memcmp(lab16_1, lab16_2, sizeof(lab16_1)) != 0) + Fail("Change format failed!"); + + trace("Ok\n"); + +} + + +// -------------------------------------------------------------------------------------------------- +// P E R F O R M A N C E C H E C K S +// -------------------------------------------------------------------------------------------------- + + +static +cmsFloat64Number MPixSec(cmsFloat64Number diff) +{ + cmsFloat64Number seconds = (cmsFloat64Number)diff / (cmsFloat64Number)CLOCKS_PER_SEC; + return (256.0 * 256.0 * 256.0) / (1024.0*1024.0*seconds); +} + +typedef cmsFloat64Number(*perf_fn)(cmsContext ct, cmsHPROFILE hlcmsProfileIn, cmsHPROFILE hlcmsProfileOut); + + +static +void PerformanceHeader(void) +{ + trace(" MPixel/sec. MByte/sec.\n"); +} + + +static +cmsHPROFILE loadProfile(const char* name) +{ + if (*name == '*') + { + if (strcmp(name, "*lab") == 0) + { + return cmsCreateLab4Profile(NULL); + } + else + if (strcmp(name, "*xyz") == 0) + { + return cmsCreateXYZProfile(); + } + else + if (strcmp(name, "*curves") == 0) + { + return CreateCurves(); + } + else + Fail("Unknown builtin '%s'", name); + + } + + return cmsOpenProfileFromFile(name, "r"); +} + + +static +cmsFloat64Number Performance(const char* Title, perf_fn fn, cmsContext ct, const char* inICC, const char* outICC, size_t sz, cmsFloat64Number prev) +{ + cmsHPROFILE hlcmsProfileIn = loadProfile(inICC); + cmsHPROFILE hlcmsProfileOut = loadProfile(outICC); + + cmsFloat64Number n = fn(ct, hlcmsProfileIn, hlcmsProfileOut); + + trace("%-30s: ", Title); fflush(stdout); + trace("%-12.2f %-12.2f", n, n * sz); + + if (prev > 0.0) { + + cmsFloat64Number imp = n / prev; + if (imp > 1) + trace(" (x %-2.1f)", imp); + } + + trace("\n"); fflush(stdout); + return n; +} + + +static +void ComparativeCt(cmsContext ct1, cmsContext ct2, const char* Title, perf_fn fn1, perf_fn fn2, const char* inICC, const char* outICC) +{ + cmsHPROFILE hlcmsProfileIn; + cmsHPROFILE hlcmsProfileOut; + + if (inICC == NULL) + hlcmsProfileIn = CreateCurves(); + else + hlcmsProfileIn = cmsOpenProfileFromFile(inICC, "r"); + + if (outICC == NULL) + hlcmsProfileOut = CreateCurves(); + else + hlcmsProfileOut = cmsOpenProfileFromFile(outICC, "r"); + + + cmsFloat64Number n1 = fn1(ct1, hlcmsProfileIn, hlcmsProfileOut); + + if (inICC == NULL) + hlcmsProfileIn = CreateCurves(); + else + hlcmsProfileIn = cmsOpenProfileFromFile(inICC, "r"); + + if (outICC == NULL) + hlcmsProfileOut = CreateCurves(); + else + hlcmsProfileOut = cmsOpenProfileFromFile(outICC, "r"); + + cmsFloat64Number n2 = fn2(ct2, hlcmsProfileIn, hlcmsProfileOut); + + + trace("%-30s: ", Title); fflush(stdout); + trace("%-12.2f %-12.2f\n", n1, n2); +} + +static +void Comparative(const char* Title, perf_fn fn1, perf_fn fn2, const char* inICC, const char* outICC) +{ + ComparativeCt(0, 0, Title, fn1, fn2, inICC, outICC); +} + +// The worst case is used, no cache and all rgb combinations +static +cmsFloat64Number SpeedTest8bitsRGB(cmsContext ct, cmsHPROFILE hlcmsProfileIn, cmsHPROFILE hlcmsProfileOut) +{ + cmsInt32Number r, g, b, j; + clock_t atime; + cmsFloat64Number diff; + cmsHTRANSFORM hlcmsxform; + Scanline_rgb8bits *In; + cmsUInt32Number Mb; + + if (hlcmsProfileIn == NULL || hlcmsProfileOut == NULL) + Fail("Unable to open profiles"); + + hlcmsxform = cmsCreateTransformTHR(ct, hlcmsProfileIn, TYPE_RGB_8, hlcmsProfileOut, TYPE_RGB_8, INTENT_PERCEPTUAL, cmsFLAGS_NOCACHE); + cmsCloseProfile(hlcmsProfileIn); + cmsCloseProfile(hlcmsProfileOut); + + Mb = 256 * 256 * 256 * sizeof(Scanline_rgb8bits); + In = (Scanline_rgb8bits*)malloc(Mb); + + j = 0; + for (r = 0; r < 256; r++) + for (g = 0; g < 256; g++) + for (b = 0; b < 256; b++) { + + In[j].r = (cmsUInt8Number)r; + In[j].g = (cmsUInt8Number)g; + In[j].b = (cmsUInt8Number)b; + + j++; + } + + atime = clock(); + + cmsDoTransform(hlcmsxform, In, In, 256 * 256 * 256); + + diff = clock() - atime; + free(In); + + cmsDeleteTransform(hlcmsxform); + + return MPixSec(diff); +} + +static +cmsFloat64Number SpeedTest8bitsRGBA(cmsContext ct, cmsHPROFILE hlcmsProfileIn, cmsHPROFILE hlcmsProfileOut) +{ + cmsInt32Number r, g, b, j; + clock_t atime; + cmsFloat64Number diff; + cmsHTRANSFORM hlcmsxform; + Scanline_rgba8bits *In; + cmsUInt32Number Mb; + + if (hlcmsProfileIn == NULL || hlcmsProfileOut == NULL) + Fail("Unable to open profiles"); + + hlcmsxform = cmsCreateTransformTHR(ct, hlcmsProfileIn, TYPE_RGBA_8, hlcmsProfileOut, TYPE_RGBA_8, INTENT_PERCEPTUAL, cmsFLAGS_NOCACHE); + cmsCloseProfile(hlcmsProfileIn); + cmsCloseProfile(hlcmsProfileOut); + + Mb = 256 * 256 * 256 * sizeof(Scanline_rgba8bits); + In = (Scanline_rgba8bits*)malloc(Mb); + + j = 0; + for (r = 0; r < 256; r++) + for (g = 0; g < 256; g++) + for (b = 0; b < 256; b++) { + + In[j].r = (cmsUInt8Number)r; + In[j].g = (cmsUInt8Number)g; + In[j].b = (cmsUInt8Number)b; + In[j].a = 0; + + j++; + } + + atime = clock(); + + cmsDoTransform(hlcmsxform, In, In, 256 * 256 * 256); + + diff = clock() - atime; + free(In); + + cmsDeleteTransform(hlcmsxform); + return MPixSec(diff); + +} + + +// The worst case is used, no cache and all rgb combinations +static +cmsFloat64Number SpeedTest16bitsRGB(cmsContext ct, cmsHPROFILE hlcmsProfileIn, cmsHPROFILE hlcmsProfileOut) +{ + cmsInt32Number r, g, b, j; + clock_t atime; + cmsFloat64Number diff; + cmsHTRANSFORM hlcmsxform; + Scanline_rgb16bits *In; + cmsUInt32Number Mb; + + if (hlcmsProfileIn == NULL || hlcmsProfileOut == NULL) + Fail("Unable to open profiles"); + + hlcmsxform = cmsCreateTransformTHR(ct, hlcmsProfileIn, TYPE_RGB_16, hlcmsProfileOut, TYPE_RGB_16, INTENT_PERCEPTUAL, cmsFLAGS_NOCACHE); + cmsCloseProfile(hlcmsProfileIn); + cmsCloseProfile(hlcmsProfileOut); + + Mb = 256 * 256 * 256 * sizeof(Scanline_rgb16bits); + In = (Scanline_rgb16bits*)malloc(Mb); + + j = 0; + for (r = 0; r < 256; r++) + for (g = 0; g < 256; g++) + for (b = 0; b < 256; b++) { + + In[j].r = (cmsUInt16Number)FROM_8_TO_16(r); + In[j].g = (cmsUInt16Number)FROM_8_TO_16(g); + In[j].b = (cmsUInt16Number)FROM_8_TO_16(b); + + j++; + } + + atime = clock(); + + cmsDoTransform(hlcmsxform, In, In, 256 * 256 * 256); + + diff = clock() - atime; + free(In); + + cmsDeleteTransform(hlcmsxform); + + return MPixSec(diff); +} + +static +cmsFloat64Number SpeedTest16bitsCMYK(cmsContext ct, cmsHPROFILE hlcmsProfileIn, cmsHPROFILE hlcmsProfileOut) +{ + + cmsInt32Number r, g, b, j; + clock_t atime; + cmsFloat64Number diff; + cmsHTRANSFORM hlcmsxform; + Scanline_cmyk16bits* In; + cmsUInt32Number Mb; + + if (hlcmsProfileIn == NULL || hlcmsProfileOut == NULL) + Fail("Unable to open profiles"); + + hlcmsxform = cmsCreateTransformTHR(ct, hlcmsProfileIn, TYPE_CMYK_16, hlcmsProfileOut, TYPE_CMYK_16, INTENT_PERCEPTUAL, cmsFLAGS_NOCACHE); + cmsCloseProfile(hlcmsProfileIn); + cmsCloseProfile(hlcmsProfileOut); + + Mb = 256 * 256 * 256 * sizeof(Scanline_cmyk16bits); + In = (Scanline_cmyk16bits*)malloc(Mb); + + j = 0; + for (r = 0; r < 256; r++) + for (g = 0; g < 256; g++) + for (b = 0; b < 256; b++) { + + In[j].c = (cmsUInt16Number)r; + In[j].m = (cmsUInt16Number)g; + In[j].y = (cmsUInt16Number)b; + In[j].k = (cmsUInt16Number)r; + + j++; + } + + atime = clock(); + + cmsDoTransform(hlcmsxform, In, In, 256 * 256 * 256); + + diff = clock() - atime; + free(In); + + cmsDeleteTransform(hlcmsxform); + return MPixSec(diff); +} + + +static +void SpeedTest8(void) +{ + cmsContext noPlugin = cmsCreateContext(0, 0); + + cmsFloat64Number t[10]; + + trace("\n\n"); + trace("P E R F O R M A N C E T E S T S 8 B I T S (D E F A U L T)\n"); + trace("==============================================================\n\n"); + fflush(stdout); + + PerformanceHeader(); + t[0] = Performance("8 bits on CLUT profiles ", SpeedTest8bitsRGB, noPlugin, "test5.icc", "test3.icc", sizeof(Scanline_rgb8bits), 0); + t[1] = Performance("8 bits on Matrix-Shaper ", SpeedTest8bitsRGB, noPlugin, "test5.icc", "test0.icc", sizeof(Scanline_rgb8bits), 0); + t[2] = Performance("8 bits on same MatrixSh ", SpeedTest8bitsRGB, noPlugin, "test0.icc", "test0.icc", sizeof(Scanline_rgb8bits), 0); + t[3] = Performance("8 bits on curves ", SpeedTest8bitsRGB, noPlugin, "*curves", "*curves", sizeof(Scanline_rgb8bits), 0); + + // Note that context 0 has the plug-in installed + + trace("\n\n"); + trace("P E R F O R M A N C E T E S T S 8 B I T S (P L U G I N)\n"); + trace("===========================================================\n\n"); + fflush(stdout); + + PerformanceHeader(); + Performance("8 bits on CLUT profiles ", SpeedTest8bitsRGB, 0, "test5.icc", "test3.icc", sizeof(Scanline_rgb8bits), t[0]); + Performance("8 bits on Matrix-Shaper ", SpeedTest8bitsRGB, 0, "test5.icc", "test0.icc", sizeof(Scanline_rgb8bits), t[1]); + Performance("8 bits on same MatrixSh ", SpeedTest8bitsRGB, 0, "test0.icc", "test0.icc", sizeof(Scanline_rgb8bits), t[2]); + Performance("8 bits on curves ", SpeedTest8bitsRGB, 0, "*curves", "*curves", sizeof(Scanline_rgb8bits), t[3]); + + cmsDeleteContext(noPlugin); +} + +static +void SpeedTest16(void) +{ + cmsContext noPlugin = cmsCreateContext(0, 0); + + cmsFloat64Number t[10]; + + trace("\n\n"); + trace("P E R F O R M A N C E T E S T S 1 6 B I T S (D E F A U L T)\n"); + trace("=================================================================\n\n"); + + PerformanceHeader(); + t[0] = Performance("16 bits on CLUT profiles ", SpeedTest16bitsRGB, noPlugin, "test5.icc", "test3.icc", sizeof(Scanline_rgb16bits), 0); + t[1] = Performance("16 bits on Matrix-Shaper profiles", SpeedTest16bitsRGB, noPlugin, "test5.icc", "test0.icc", sizeof(Scanline_rgb16bits), 0); + t[2] = Performance("16 bits on same Matrix-Shaper ", SpeedTest16bitsRGB, noPlugin, "test0.icc", "test0.icc", sizeof(Scanline_rgb16bits), 0); + t[3] = Performance("16 bits on curves ", SpeedTest16bitsRGB, noPlugin, "*curves", "*curves", sizeof(Scanline_rgb16bits), 0); + t[4] = Performance("16 bits on CMYK CLUT profiles ", SpeedTest16bitsCMYK, noPlugin, "test1.icc", "test2.icc", sizeof(Scanline_cmyk16bits), 0); + + trace("\n\n"); + trace("P E R F O R M A N C E T E S T S 1 6 B I T S (P L U G I N)\n"); + trace("===============================================================\n\n"); + + PerformanceHeader(); + Performance("16 bits on CLUT profiles ", SpeedTest16bitsRGB, 0, "test5.icc", "test3.icc", sizeof(Scanline_rgb16bits), t[0]); + Performance("16 bits on Matrix-Shaper profiles", SpeedTest16bitsRGB, 0, "test5.icc", "test0.icc", sizeof(Scanline_rgb16bits), t[1]); + Performance("16 bits on same Matrix-Shaper ", SpeedTest16bitsRGB, 0, "test0.icc", "test0.icc", sizeof(Scanline_rgb16bits), t[2]); + Performance("16 bits on curves ", SpeedTest16bitsRGB, 0, "*curves", "*curves", sizeof(Scanline_rgb16bits), t[3]); + Performance("16 bits on CMYK CLUT profiles ", SpeedTest16bitsCMYK, 0, "test1.icc", "test2.icc", sizeof(Scanline_cmyk16bits), t[4]); +} + + + +typedef struct +{ + Scanline_rgba8bits pixels[256][256]; + cmsUInt8Number padding[4]; + +} padded_line; + +typedef struct +{ + padded_line line[256]; +} big_bitmap; + + +static +cmsFloat64Number SpeedTest8bitDoTransform(cmsContext ct, cmsHPROFILE hlcmsProfileIn, cmsHPROFILE hlcmsProfileOut) +{ + cmsInt32Number r, g, b, j; + clock_t atime; + cmsFloat64Number diff; + cmsHTRANSFORM hlcmsxform; + big_bitmap* In; + big_bitmap* Out; + cmsUInt32Number Mb; + + if (hlcmsProfileIn == NULL || hlcmsProfileOut == NULL) + Fail("Unable to open profiles"); + + hlcmsxform = cmsCreateTransformTHR(ct, hlcmsProfileIn, TYPE_RGBA_8, hlcmsProfileOut, TYPE_RGBA_8, INTENT_PERCEPTUAL, cmsFLAGS_NOCACHE); + cmsCloseProfile(hlcmsProfileIn); + cmsCloseProfile(hlcmsProfileOut); + + + // Our test bitmap is 256 x 256 padded lines + Mb = sizeof(big_bitmap); + + In = (big_bitmap*)malloc(Mb); + Out = (big_bitmap*)malloc(Mb); + + for (r = 0; r < 256; r++) + for (g = 0; g < 256; g++) + for (b = 0; b < 256; b++) { + + In->line[r].pixels[g][b].r = (cmsUInt8Number)r; + In->line[r].pixels[g][b].g = (cmsUInt8Number)g; + In->line[r].pixels[g][b].b = (cmsUInt8Number)b; + In->line[r].pixels[g][b].a = 0; + } + + atime = clock(); + + for (j = 0; j < 256; j++) { + + cmsDoTransform(hlcmsxform, In->line[j].pixels, Out->line[j].pixels, 256 * 256); + } + + diff = clock() - atime; + free(In); free(Out); + + cmsDeleteTransform(hlcmsxform); + return MPixSec(diff); + +} + + +static +cmsFloat64Number SpeedTest8bitLineStride(cmsContext ct, cmsHPROFILE hlcmsProfileIn, cmsHPROFILE hlcmsProfileOut) +{ + cmsInt32Number r, g, b; + clock_t atime; + cmsFloat64Number diff; + cmsHTRANSFORM hlcmsxform; + big_bitmap* In; + big_bitmap* Out; + cmsUInt32Number Mb; + + if (hlcmsProfileIn == NULL || hlcmsProfileOut == NULL) + Fail("Unable to open profiles"); + + hlcmsxform = cmsCreateTransformTHR(ct, hlcmsProfileIn, TYPE_RGBA_8, hlcmsProfileOut, TYPE_RGBA_8, INTENT_PERCEPTUAL, cmsFLAGS_NOCACHE); + cmsCloseProfile(hlcmsProfileIn); + cmsCloseProfile(hlcmsProfileOut); + + + // Our test bitmap is 256 x 256 padded lines + Mb = sizeof(big_bitmap); + + In = (big_bitmap*)malloc(Mb); + Out = (big_bitmap*)malloc(Mb); + + for (r = 0; r < 256; r++) + for (g = 0; g < 256; g++) + for (b = 0; b < 256; b++) { + + In->line[r].pixels[g][b].r = (cmsUInt8Number)r; + In->line[r].pixels[g][b].g = (cmsUInt8Number)g; + In->line[r].pixels[g][b].b = (cmsUInt8Number)b; + In->line[r].pixels[g][b].a = 0; + } + + atime = clock(); + + cmsDoTransformLineStride(hlcmsxform, In, Out, 256*256, 256, sizeof(padded_line), sizeof(padded_line), 0, 0); + + diff = clock() - atime; + free(In); free(Out); + + cmsDeleteTransform(hlcmsxform); + return MPixSec(diff); + +} + +static +void ComparativeLineStride8bits(void) +{ + cmsContext NoPlugin, Plugin; + + trace("\n\n"); + trace("C O M P A R A T I V E cmsDoTransform() vs. cmsDoTransformLineStride()\n"); + trace(" values given in MegaPixels per second.\n"); + trace("====================================================================\n"); + + fflush(stdout); + + NoPlugin = cmsCreateContext(NULL, NULL); + Plugin = cmsCreateContext(cmsThreadedExtensions(CMS_THREADED_GUESS_MAX_THREADS, 0), NULL); + + ComparativeCt(NoPlugin, Plugin, "CLUT profiles ", SpeedTest8bitDoTransform, SpeedTest8bitLineStride, "test5.icc", "test3.icc"); + ComparativeCt(NoPlugin, Plugin, "CLUT 16 bits ", SpeedTest16bitsRGB, SpeedTest16bitsRGB, "test5.icc", "test3.icc"); + ComparativeCt(NoPlugin, Plugin, "Matrix-Shaper ", SpeedTest8bitDoTransform, SpeedTest8bitLineStride, "test5.icc", "test0.icc"); + ComparativeCt(NoPlugin, Plugin, "same MatrixSh ", SpeedTest8bitDoTransform, SpeedTest8bitLineStride, "test0.icc", "test0.icc"); + ComparativeCt(NoPlugin, Plugin, "curves ", SpeedTest8bitDoTransform, SpeedTest8bitLineStride, NULL, NULL); + + cmsDeleteContext(Plugin); + cmsDeleteContext(NoPlugin); +} + + + +// The harness test +int main() +{ + trace("Multithreaded extensions testbed - 1.0\n"); + trace("Copyright (c) 1998-2022 Marti Maria Saguer, all rights reserved\n"); + + trace("\nInstalling error logger ... "); + cmsSetLogErrorHandler(FatalErrorQuit); + trace("done.\n"); + + trace("Installing plug-in ... "); + cmsPlugin(cmsThreadedExtensions(CMS_THREADED_GUESS_MAX_THREADS, 0)); + trace("done.\n\n"); + + // Change format + CheckChangeFormat(); + + // Check speed + SpeedTest8(); + SpeedTest16(); + ComparativeLineStride8bits(); + + trace("\nAll tests passed OK\n"); + return 0; +} + + + diff --git a/src/cmserr.c b/src/cmserr.c index 1563b7b..0078886 100644 --- a/src/cmserr.c +++ b/src/cmserr.c @@ -613,7 +613,6 @@ cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Data) if (Plugin ->CreateMutexPtr == NULL || Plugin ->DestroyMutexPtr == NULL || Plugin ->LockMutexPtr == NULL || Plugin ->UnlockMutexPtr == NULL) return FALSE; - ctx->CreateMutexPtr = Plugin->CreateMutexPtr; ctx->DestroyMutexPtr = Plugin ->DestroyMutexPtr; ctx ->LockMutexPtr = Plugin ->LockMutexPtr; @@ -661,3 +660,47 @@ void CMSEXPORT _cmsUnlockMutex(cmsContext ContextID, void* mtx) ptr ->UnlockMutexPtr(ContextID, mtx); } } + +// The global Context0 storage for parallelization plug-in + _cmsParallelizationPluginChunkType _cmsParallelizationPluginChunk = { 0 }; + +// Allocate parallelization container. +void _cmsAllocParallelizationPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src) +{ + if (src != NULL) { + void* from = src->chunks[ParallelizationPlugin]; + ctx->chunks[ParallelizationPlugin] = _cmsSubAllocDup(ctx->MemPool, from, sizeof(_cmsParallelizationPluginChunkType)); + } + else { + _cmsParallelizationPluginChunkType ParallelizationPluginChunk = { 0 }; + ctx->chunks[ParallelizationPlugin] = _cmsSubAllocDup(ctx->MemPool, &ParallelizationPluginChunk, sizeof(_cmsParallelizationPluginChunkType)); + } +} + +// Register parallel processing +cmsBool _cmsRegisterParallelizationPlugin(cmsContext ContextID, cmsPluginBase* Data) +{ + cmsPluginParalellization* Plugin = (cmsPluginParalellization*)Data; + _cmsParallelizationPluginChunkType* ctx = (_cmsParallelizationPluginChunkType*)_cmsContextGetClientChunk(ContextID, ParallelizationPlugin); + + if (Data == NULL) { + + // No parallelization routines + ctx->MaxWorkers = 0; + ctx->WorkerFlags = 0; + ctx->SchedulerFn = NULL; + return TRUE; + } + + // callback is required + if (Plugin->SchedulerFn == NULL) return FALSE; + + ctx->MaxWorkers = Plugin->MaxWorkers; + ctx->WorkerFlags = Plugin->WorkerFlags; + ctx->SchedulerFn = Plugin->SchedulerFn; + + // All is ok + return TRUE; +} + diff --git a/src/cmshalf.c b/src/cmshalf.c index 7a96959..57cb5b0 100644 --- a/src/cmshalf.c +++ b/src/cmshalf.c @@ -377,7 +377,7 @@ static const cmsUInt32Number Mantissa[2048] = { 0x387fc000, 0x387fe000 }; -static cmsUInt16Number Offset[64] = { +static const cmsUInt16Number Offset[64] = { 0x0000, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, diff --git a/src/cmsplugin.c b/src/cmsplugin.c index dbda3fd..f581719 100644 --- a/src/cmsplugin.c +++ b/src/cmsplugin.c @@ -621,6 +621,10 @@ cmsBool CMSEXPORT cmsPluginTHR(cmsContext id, void* Plug_in) if (!_cmsRegisterMutexPlugin(id, Plugin)) return FALSE; break; + case cmsPluginParalellizationSig: + if (!_cmsRegisterParallelizationPlugin(id, Plugin)) return FALSE; + break; + default: cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type); return FALSE; @@ -643,24 +647,25 @@ void CMSEXPORT cmsUnregisterPlugins(void) // pointers structure. All global vars are referenced here. static struct _cmsContext_struct globalContext = { - NULL, // Not in the linked list - NULL, // No suballocator - { - NULL, // UserPtr, - &_cmsLogErrorChunk, // Logger, - &_cmsAlarmCodesChunk, // AlarmCodes, - &_cmsAdaptationStateChunk, // AdaptationState, - &_cmsMemPluginChunk, // MemPlugin, - &_cmsInterpPluginChunk, // InterpPlugin, - &_cmsCurvesPluginChunk, // CurvesPlugin, - &_cmsFormattersPluginChunk, // FormattersPlugin, - &_cmsTagTypePluginChunk, // TagTypePlugin, - &_cmsTagPluginChunk, // TagPlugin, - &_cmsIntentsPluginChunk, // IntentPlugin, - &_cmsMPETypePluginChunk, // MPEPlugin, - &_cmsOptimizationPluginChunk, // OptimizationPlugin, - &_cmsTransformPluginChunk, // TransformPlugin, - &_cmsMutexPluginChunk // MutexPlugin + NULL, // Not in the linked list + NULL, // No suballocator + { + NULL, // UserPtr, + &_cmsLogErrorChunk, // Logger, + &_cmsAlarmCodesChunk, // AlarmCodes, + &_cmsAdaptationStateChunk, // AdaptationState, + &_cmsMemPluginChunk, // MemPlugin, + &_cmsInterpPluginChunk, // InterpPlugin, + &_cmsCurvesPluginChunk, // CurvesPlugin, + &_cmsFormattersPluginChunk, // FormattersPlugin, + &_cmsTagTypePluginChunk, // TagTypePlugin, + &_cmsTagPluginChunk, // TagPlugin, + &_cmsIntentsPluginChunk, // IntentPlugin, + &_cmsMPETypePluginChunk, // MPEPlugin, + &_cmsOptimizationPluginChunk, // OptimizationPlugin, + &_cmsTransformPluginChunk, // TransformPlugin, + &_cmsMutexPluginChunk, // MutexPlugin, + &_cmsParallelizationPluginChunk // ParallelizationPlugin }, { NULL, NULL, NULL, NULL, NULL, NULL } // The default memory allocator is not used for context 0 @@ -798,6 +803,7 @@ void CMSEXPORT cmsUnregisterPluginsTHR(cmsContext ContextID) _cmsRegisterOptimizationPlugin(ContextID, NULL); _cmsRegisterTransformPlugin(ContextID, NULL); _cmsRegisterMutexPlugin(ContextID, NULL); + _cmsRegisterParallelizationPlugin(ContextID, NULL); } @@ -881,6 +887,7 @@ cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData) _cmsAllocOptimizationPluginChunk(ctx, NULL); _cmsAllocTransformPluginChunk(ctx, NULL); _cmsAllocMutexPluginChunk(ctx, NULL); + _cmsAllocParallelizationPluginChunk(ctx, NULL); // Setup the plug-ins if (!cmsPluginTHR(ctx, Plugin)) { @@ -944,6 +951,7 @@ cmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData) _cmsAllocOptimizationPluginChunk(ctx, src); _cmsAllocTransformPluginChunk(ctx, src); _cmsAllocMutexPluginChunk(ctx, src); + _cmsAllocParallelizationPluginChunk(ctx, src); // Make sure no one failed for (i=Logger; i < MemoryClientMax; i++) { diff --git a/src/cmsxform.c b/src/cmsxform.c index c7183fc..7f6636e 100644 --- a/src/cmsxform.c +++ b/src/cmsxform.c @@ -781,6 +781,43 @@ cmsUInt32Number CMSEXPORT _cmsGetTransformFlags(struct _cmstransform_struct* CMM return CMMcargo->dwOriginalFlags; } +// Returns the worker callback for parallelization plug-ins +_cmsTransform2Fn CMSEXPORT _cmsGetTransformWorker(struct _cmstransform_struct* CMMcargo) +{ + _cmsAssert(CMMcargo != NULL); + return CMMcargo->Worker; +} + +// This field holds maximum number of workers or -1 to auto +cmsInt32Number CMSEXPORT _cmsGetTransformMaxWorkers(struct _cmstransform_struct* CMMcargo) +{ + _cmsAssert(CMMcargo != NULL); + return CMMcargo->MaxWorkers; +} + +// This field is actually unused and reserved +cmsUInt32Number CMSEXPORT _cmsGetTransformWorkerFlags(struct _cmstransform_struct* CMMcargo) +{ + _cmsAssert(CMMcargo != NULL); + return CMMcargo->WorkerFlags; +} + +// In the case there is a parallelization plug-in, let it to do its job +static +void ParalellizeIfSuitable(_cmsTRANSFORM* p) +{ + _cmsParallelizationPluginChunkType* ctx = (_cmsParallelizationPluginChunkType*)_cmsContextGetClientChunk(p->ContextID, ParallelizationPlugin); + + _cmsAssert(p != NULL); + if (ctx != NULL && ctx->SchedulerFn != NULL) { + + p->Worker = p->xform; + p->xform = ctx->SchedulerFn; + p->MaxWorkers = ctx->MaxWorkers; + p->WorkerFlags = ctx->WorkerFlags; + } +} + // Allocate transform struct and set it to defaults. Ask the optimization plug-in about if those formats are proper // for separated transforms. If this is the case, static @@ -836,6 +873,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut, p->xform = _cmsTransform2toTransformAdaptor; } + ParalellizeIfSuitable(p); return p; } } @@ -924,6 +962,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut, p ->dwOriginalFlags = *dwFlags; p ->ContextID = ContextID; p ->UserData = NULL; + ParalellizeIfSuitable(p); return p; } diff --git a/src/lcms2_internal.h b/src/lcms2_internal.h index ecb5baf..94282a4 100644 --- a/src/lcms2_internal.h +++ b/src/lcms2_internal.h @@ -283,38 +283,38 @@ typedef CRITICAL_SECTION _cmsMutex; cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) { - EnterCriticalSection(m); - return 0; + EnterCriticalSection(m); + return 0; } cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) { - LeaveCriticalSection(m); - return 0; + LeaveCriticalSection(m); + return 0; } - + cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) { - InitializeCriticalSection(m); - return 0; + InitializeCriticalSection(m); + return 0; } cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) { - DeleteCriticalSection(m); - return 0; + DeleteCriticalSection(m); + return 0; } cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) { - EnterCriticalSection(m); - return 0; + EnterCriticalSection(m); + return 0; } cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m) { - LeaveCriticalSection(m); - return 0; + LeaveCriticalSection(m); + return 0; } #else @@ -328,32 +328,32 @@ typedef pthread_mutex_t _cmsMutex; cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) { - return pthread_mutex_lock(m); + return pthread_mutex_lock(m); } cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) { - return pthread_mutex_unlock(m); + return pthread_mutex_unlock(m); } - + cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) { - return pthread_mutex_init(m, NULL); + return pthread_mutex_init(m, NULL); } cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) { - return pthread_mutex_destroy(m); + return pthread_mutex_destroy(m); } cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) { - return pthread_mutex_lock(m); + return pthread_mutex_lock(m); } cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m) { - return pthread_mutex_unlock(m); + return pthread_mutex_unlock(m); } #endif @@ -366,37 +366,37 @@ typedef int _cmsMutex; cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) { cmsUNUSED_PARAMETER(m); - return 0; + return 0; } cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) { cmsUNUSED_PARAMETER(m); - return 0; + return 0; } - + cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) { cmsUNUSED_PARAMETER(m); - return 0; + return 0; } cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) { cmsUNUSED_PARAMETER(m); - return 0; + return 0; } cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) { cmsUNUSED_PARAMETER(m); - return 0; + return 0; } cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m) { cmsUNUSED_PARAMETER(m); - return 0; + return 0; } #endif @@ -438,6 +438,9 @@ cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin // Mutex cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin); +// Paralellization +cmsBool _cmsRegisterParallelizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin); + // --------------------------------------------------------------------------------------------------------- // Suballocators. @@ -485,6 +488,7 @@ typedef enum { OptimizationPlugin, TransformPlugin, MutexPlugin, + ParallelizationPlugin, // Last in list MemoryClientMax @@ -720,6 +724,24 @@ extern _cmsMutexPluginChunkType _cmsMutexPluginChunk; void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsContext_struct* src); +// Container for parallelization plug-in +typedef struct { + + cmsInt32Number MaxWorkers; // Number of workers to do as maximum + cmsInt32Number WorkerFlags; // reserved + _cmsTransform2Fn SchedulerFn; // callback to setup functions + +} _cmsParallelizationPluginChunkType; + +// The global Context0 storage for parallelization plug-in +extern _cmsParallelizationPluginChunkType _cmsParallelizationPluginChunk; + +// Allocate parallelization container. +void _cmsAllocParallelizationPluginChunk(struct _cmsContext_struct* ctx, + const struct _cmsContext_struct* src); + + + // ---------------------------------------------------------------------------------- // MLU internal representation typedef struct { @@ -1081,6 +1103,11 @@ typedef struct _cmstransform_struct { // A way to provide backwards compatibility with full xform plugins _cmsTransformFn OldXform; + // A one-worker transform entry for parallelization + _cmsTransform2Fn Worker; + cmsInt32Number MaxWorkers; + cmsUInt32Number WorkerFlags; + } _cmsTRANSFORM; // Copies extra channels from input to output if the original flags in the transform structure diff --git a/testbed/new.icc b/testbed/new.icc index 53b3505..bd90c3d 100644 Binary files a/testbed/new.icc and b/testbed/new.icc differ diff --git a/testbed/testbed.exp b/testbed/testbed.exp new file mode 100644 index 0000000..376be96 Binary files /dev/null and b/testbed/testbed.exp differ diff --git a/testbed/testcms2.c b/testbed/testcms2.c index 838c160..717b1c9 100644 --- a/testbed/testcms2.c +++ b/testbed/testcms2.c @@ -8384,11 +8384,11 @@ int CheckGammaSpaceDetection(void) return 1; } -// Per issue #308. A built-in corrypted by using write raw tag was causing a segfault +// Per issue #308. A built-in is corrupted by using write raw tag was causing a segfault static int CheckInducedCorruption(void) { - cmsHTRANSFORM xform0, xform1; + cmsHTRANSFORM xform0; char garbage[] = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b"; cmsHPROFILE hsrgb = cmsCreate_sRGBProfile(); cmsHPROFILE hLab = cmsCreateLab4Profile(NULL); -- cgit v1.2.1